Hello,everyone. 浅浅整理了一些java基础知识,希望帮到大家,如果有哪些地方写的不对还望指正。
标识符注意点
-
所有的标识符都应该以字母,美元符$,或者下划线_开始
-
首字母之后可以是字母,美元符,下划线或数字的任何字符组合
-
不能用关键字作为变量名或方法名
-
标识符是大小写敏感的
类型转换
低------------------------------------------------>高
byte,short,char->int->long->float->double
运算中,不同类型的数据先转化为同一类型,然后进行运算
-
强制类型转换 //(类型)变量名 高–>低
-
自动类型转换 //低---->高
注意
1不能对布尔值转换
2不能把对象转换为不相干的类型
3在把高容量转换到低容量的时候,强制转换
4转换的时候可能存在内存溢出,或者精度问题
数据类型
基本类型:八大类型
byte 占一个字节-128——127
short 占两个字节 -32768——32767
int 占4个字节 -2147483648——2147483647
long 占8个字节 -9223372036854775808——9223372036854775807
float 占4个字节
double 占8个字节
char字符型
boolean类型 :占1位 其值只有true和false两个
引用类型
- 类
- 接口
- 数组
变量
Java是一种强类型语言,每个变量都必须声明其类型
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域
格式:
数据类型 变量名 = 值; //可以使用逗号隔开来声明多个同类型变量
变量作用域
-
类变量
-
实例变量
-
局部变量
public class Variable{
static int allClicks=0;//类变量
String str =“hello world”;//实例变量
public void method(){
int i=0;//局部变量
}
}
常量
初始化后不能再改变值
格式:
final 常量名=值;
final double PI=3.14;
常量一般使用大写字符
变量的命名规范
- 所有变量、方法、类名:见名知意
- 类成员变量:首字母小写和驼峰原则:除了第一个单词以外,后面单词首字母大写(lastName)
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下划线(MAX_VALUE)
- 类名:首字母大写和驼峰原则
- 方法名:首字母小写和驼峰原则
运算符 优先级()
- 算术运算符:+ ,-, *, /,%,++,–
- 赋值运算符:=
- 关系运算符:>,<,>=,<=,==,!=,instanceof
- 逻辑运算符:&&,||,!
- 位运算符:&,|,~,^,>>,<<,>>>
- 条件运算符: ? :
- 扩展赋值运算符:+=,-=,*=,/+
包机制
为了更好地组织类,Java提供了包机制,用于区分类名的命名空间
包语句的语法格式为:
package pkg1[.pkg2[.pkg3…]]
一般利用公司域名倒置作为包名
为了能使用某一个包的成员,我们需要在Java程序中明确导入该包。使用“import”语句可完成此功能
import package1[.package2[.package3…]] (必须放在上条语句的下方)
“*”这是一个符号,只要在某个包后面加上它,就可以使用该包里面的所有类
Scanner对象
scanner类可以用来获取用户的输入
基本语法:
Scanner s = new Scanner(System.in);
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据
-
next():
- 一定要读取到有效字符后才可以结束输入
- 对输入有效字符之前遇到的空白,next()方法会自动将其去掉
- 只有输入有效字符后才能将其后面输入的空白作为分隔符或者结束符
- next()不能得到带有空格的字符串
-
nextLine():
- 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符
- 可以获得空白
switch多选择结构
它的语句中变量类型可以是:
- byte/short/int/char
- 从Java SE 7开始,switch支持字符串String 类型了
- 同时case标签必须是字符串常量或者字面量
For循环
这是支持迭代的一种通用结构,是最有效、最灵活的循环结构
增强for循环
数组重点使用
for (声明语句 : 表达式)
{
//代码句子
}
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法
break continue
- break:在任何循环语句的主体部分,均可用它控制循环的流程。它用于强行退出循环,不执行循环中剩余的语句(break 在switch语句中也使用)
- continue:它在循环语句中,用于终止某次循环过程,即跳过循环体内尚未执行的语句,接着进行下一次是否执行的判定
- 关于goto关键字:goto关键字在程序设计语言中出现,尽管goto仍是java 的一个保留字,但并未在语言上正式使用;Java没有goto,然而,在break continue这两个关键字的身上,我们仍然可以看出一些goto的影子------带有标签的break和continue
- "标签"是指后面跟一个冒号的标识符,例如:lable
- 对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若同标签使用,他们就会中断到存在标签的地方。
Java方法
它是语句的集合,它们在一起执行一个功能。
方法是解决一类问题步骤的有序组合
方法包含于类或对象中
方法在程序被创建,在其他地方被引用
设计方法的原则:方法的本意是功能块,就是实现某个功能语句块的集合,我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样有利于我们后期的拓展
方法的定义
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法,定义了该方法的访问类型
- 返回值类型:方法可能会返回值。如果为void,则表示没有return语句,也可以直接写成return; 返回值类型可以是任意类型。返回值类型与return返回值的类型必须一致或兼容(兼容是指return的返回值可以自动转换成返回值类型)。
- 一个方法最多有一个返回值,如果想返回多个结果,可以用数组接收
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数变量是指方法的参数类型、顺序和参数的个数。实参和形参的类型一定要一致或者兼容、个数、顺序必须一致。形参和实参可以是任意类型。
- 形式参数:在方法被调用时用于接受外界输入的数据
- 实参:调用方法时实际传给方法的数据
- 方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
…
方法体
…
return 返回值
}
方法体里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即:方法不能嵌套定义
方法调用
-
如果同一个类中的方法调用,直接调用即可:方法名(实参列表) 如果跨类中的方法A调用B类方法,需要先创建对象,然后通过对象名调用方法:对象名.方法名(实参列表)
-
跨类的方法调用和方法的访问修饰符有关
-
方法写好后,如果不去调用,就不会输出
-
Java支持两种调用方法的方式,根据方法是否返回值来选择
-
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(30,40);
-
如果方法返回值是void,方法调用一定是一条语句。
System.out.println(“Hello,kuangshen”);
-
课程拓展了解:值传递(Java)和引用传递。
方法的重载
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法重载的规则:
- 方法名称必须相同‘
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)(参数名无要求)
- 方法的返回类型不同不足以成为方法的重载
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
命令行传参
有时候你希望运行一个程序的时候再传递给它消息。这主要靠传递命令行参数给main()函数实现
可变参数
在JDK1.5开始,Java支持传递同类型的可变参数给一个方法
在方法声名中,在指定参数类型后加一个省略号(…)
一个方法只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
可变参数的实参可以为数组
可变参数的本质就是数组
可变参数可以和普通类型的参数放在一起形成形参列表,但必须保证可变参数在最后
一个形参列表只能出现一个可变参数
递归
A方法调用B方法,我们很容易理解!
递归就是:A方法调用A方法,自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
递归结构包括两部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
数组的定义
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
数组声明创建
-
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的方法:
dataType[] arrayName; //首选方法
或
dataType arrayName[];
-
Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
数组的元素是通过索引访问的,数组索引从0开始
获取数组的长度:arrays.length
数组的四个特点
- 其长度是确定的,数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的。因此无论数组保存原始类型还是其他对象类型,数组对象本身是在堆中的。
多维数组
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
Arrays类
自己动手查询找一下,可以查看一些文档
比如以下功能:
-
对数组赋值:通过fill方法
-
对数组排序:通过sort方法,按升序
-
比较数组:通过equals方法比较数组中元素值是否相等
-
查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作
(我们自己也可以写方法)
稀疏数组
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以用稀疏数组来保存该数组。
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
方法递归调用
- 执行一个方法时,就创建了一个新的受保护的独立空间(栈空间)
- 方法的局部变量是独立的,不会相互影响
- 如果方法中使用的是引用类型变量(比如数组,对象),就会共享该引用类型的数据
- 递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError
- 当一个方法执行完毕时,或者遇到return ,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。
面向过程&面向对象
-
面向过程思想
- 步骤清晰简单,第一步做什么,第二步做什么…
- 面对过程适合处理一些较为简单的问题
-
面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
-
对于描述复杂的事物,为了从宏观上把握,从整体上分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
-
面向对象编程(Object-Oriented Programming)
-
面向对象编程的本质是:以类的方式组织代码,以对象的形式封装数据。
-
抽象
-
三大特性:封装、继承、多态
-
从认识的角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
-
从代码运行角度考虑是先有类后有对象。类是对象的模板。
作用域
1.局部变量:一般是在成员方法定义的变量,作用域为定义在它的代码块中
2.全局变量(成员变量):也就是属性,作用域为整个类体
3.全局变量可以不赋值,直接使用,因为有默认值(int/byte/short/long:0 double/float:0.0 boolean:false char:\u0000 string;null)
4.局部变量必须赋值后才能使用
5.属性和局部变量可以重名,访问时遵循就近原则
6.在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名
7.属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁,即在一次方法调用的过程中。
8.全局变量(属性):可以被本类使用,也可以被其他类使用(通过对象调用)
局部变量:只能在本类中对应的方法中使用
9.全局变量(属性):可以加修饰符
局部变量:不可以加修饰符
方法的调用
静态方法
非静态方法
形参和实参
值传递和引用传递
this关键字
类与对象的关系
-
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
- 动物、植物、手机、电脑…
- Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为。
-
对象是抽象概念的具体实例
- 比如小韩就是人的一个具体实例,小韩家里的旺财就是狗的一个具体实例
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念
创建与初始化对象
-
使用new关键字创建对象
比如:Person Lucy=new Person();
对象的属性:Lucy.name;
对象的方法:Lucy.sleep();
使用new关键字创建对象的时候,除了分配内存空间外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
-
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
-
类:
- 静态的属性:属性
- 动态的行为:方法
1.对象的引用:
引用类型:基本类型
对象是通过引用来操作的:栈--------->堆
2.属性:
修饰符 属性类型 属性名=属性值;
构造器(构造方法)
前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如果我们现在要求,在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做?这个时候可以使用构造器
作用:主要是完成对新对象的初始化
基本语法:
(修饰符)方法名(形参列表){
方法体;
}
-
构造器的修饰符可以默认,也可以是public/private/protected
-
构造器没有返回值
-
方法名必须和类名一样
-
参数列表和成员方法一样的规则
-
构造器的调用由系统自动完成,构造器是完成对象的初始化,并不是创建对象
-
一个类可以定义多个不同的构造器,即构造器重载
-
如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器)
-
一旦定义了自己的构造器,默认的构造器就被覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下。
-
无参构造器:
类名(){
}
this关键字
简单地说,哪个对象调用,this就代表哪个对象
1.this关键字可以用来访问本类的属性、方法、构造器
2.this用来区分当前类的属性和局部变量
3.访问成员方法的语法:this.方法名(参数列表);
4.访问构造器语法:this(参数列表);注意只能在构造器中使用(必须写在构造器的第一行)
5.this不能再类定义的外部使用,只能在类定义的方法中使用
封装
-
该露的露,该藏的藏
-
封装(数据的隐藏)
- 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
- 属性私有,get/set
-
意义:
-
提高程序的安全性,保护数据。
-
隐藏代码的实现细节
-
统一接口
-
系统可维护增加了
-
继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
extands的意思是“扩展”。子类是父亲的扩展
java 中类只有单继承,没有多继承(一个儿子只有一个爸爸,一个爸爸可以有多个儿子)(直接继承一个,间接继承多个)
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
私有的(private)东西无法被继承
子类和父类之间,从意义上讲应该具有“is a"的关系
在java中,所有的类都默认直接或者间接继承Object类
一个Demo中只能有一个带public的类
继承的注意点:
- 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性不能在子类直接访问,要通过公共的方法去访问
- 子类必须调用父亲的构造器,完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译不会通过(如果父类什么都不写任何构造器,那么子类也可以不写,但如果父类写了有参构造器,那么子类每个构造器都要用super指明用的是父类哪个构造器)
- 如果希望指定调用父类的某个构造器,则显示的调用一下super(参数)
- super在使用时,必须放在构造器第一行
- super()和this()都只能放在构造器第一行,所以这两个方法不能共存一个构造器
- java所有类都是由Object类的子类,Object是所有类的基类
- 父类构造器的调用不限于直接父类!将一直往上追溯到Object类(顶级父类)
四个修饰符:public private default protected
同一个类 | 同一个包 | 不同包的子类 | 任何类 | |
---|---|---|---|---|
public | true | true | true | true |
protected | true | true | true | false |
default | true | true | false | false |
private | true | false | false | false |
super注意点
-
super调用父类的构造方法,必须在构造方法的第一个
-
super必须只能出现在子类的方法或者构造方法中!
-
super和this不能同时调用构造方法!
-
super代表父类的引用,用于访问父亲的属性、方法、构造器,不能访问父类的私有属性和私有方法
-
访问父类构造器是super必须放在子类构造器中
-
当子类中有和父类中的成员(属性和方法)重名时,为了访问父亲的成员,必须通过super,如果没有重名,使用super/this/直接访问 都是一样的效果
this和直接访问都是先从本类找是否有,没有再找父类,而super直接去找父类
VS this
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的引用
前提:
this:没有继承也可以使用
super:只能在继承条件下使用
构造方法:
this():本类的构造
super():父类的构造
方法重写
- 子类的参数、方法名称要和父类方法的参数、方法名称完全一样
- 子类的返回类型和父类方法返回类型一样,或者是父类返回类型的子类,比如父类的返回类型是Object,子类方法返回类型是String
- 子类方法不能缩小父类方法的访问权限:public>protected>默认(default)>private
多态
-
动态编译:类型:可扩展性
-
即同一方法可以根据发送对象的不同而采用多种不同的行为方式
-
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多
-
方法的重载体现多态
-
方法的重写体现多态
-
一个对象的编译类型和运行类型可以不一致 比如:Animal animal=new Dog(animal编译类型是Animal,运行类型是Dog)
-
编译类型在定义对象时,就确定了,不能改变
-
运行类型是可以变化的
-
编译类型看等号左边,运行类型看等号右边
-
多态的存在条件:
-
有继承关系
-
子类重写父类方法
-
父类引用指向子类对象(向上转型)
-
-
注意:多态是方法的多态,属性没有多态性,属性的值看编译类型
-
instanceOf比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型
-
父类和子类有联系,类型转换异常:ClassCastException!
-
存在条件:继承关系,方法需要重写,父类引用指向子类对象!Father f1=new Son();
-
不能被重写的方法:
1.static方法属于类,它不属于任何一个实例 2.final 常量池里面
3.private方法
-
instanceof (类型转换)引用类型,判断一个对象是什么类型
向上转型
本质:父类的引用指向了子类的对象
语法:父类类型 引用名 = new 子类类型();
特点:编译类型看左边,运行类型看右边
可以调用父类中的所有成员(需遵守访问权限)
不能调用子类中特有成员
向下转型
语法: 子类类型 引用名 = (子类类型)父类引用;
只能强转父类的引用,不能强转父类的对象
要求父类的引用必须指向的是当前目标类型的对象
当向下转型后可以调用子类类型中所有的成员
JAVA的动态绑定机制
当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
Equals
equals:是Object类中的方法,只能判断引用类型
equals默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等
==:即可以判断基本类型,又可以判断引用类型,如果判断基本类型,判断的是值是否相等;如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象
抽象类
- abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
- 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
- 抽象类:不能使用new关键字来创建对象,它是用来让子类继承的
- 抽象方法:只有方法的声明,没有方法的实现,它是用来让子类实现的
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
接口
- 普通类:只有具体实现
- 抽象类:具体实现和规范都有
- 接口:只有规范,自己无法写方法 约束和实现分离:面向接口编程
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是什么…则必须能…”的思想
声明类的关键字是class,声明接口的关键字是interface
作用:
1.约束
2.定义一些方法,让不同的人实现
3.public abstract
4.public static final
5.接口不能被实例化,接口中没有构造方法
6.implements可以实现多个接口
7.必须重写接口中的方法
内部类
内部类就是在一个类的内部再定义一个类,比如:A类中定义一个B类,那么B类相对A类来说就是内部类,而A类相对B类来说就是外部类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
异常机制
三种类型:
- 检查性异常
- 运行时异常
- 错误error
异常体系结构
Error
Exception
抛出异常
捕获异常
五个关键字:
try catch finally throw throws
自定义异常
大致分以下几个步骤:
- 创建自定义异常类
- 在方法中通过throw关键字抛出异常对象
- 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步的操作
- 在出现异常方法的调用者中捕获并处理异常
经验总结:
- 处理运行异常时,采用逻辑去合理规避同时辅助try-catch处理
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
- 对于不确定的代码,也可加上try-catch,处理潜在异常
- 尽量添加finally语句块去释放占用的资源
感谢阅读,有空会更新的~