Java基础
Java入门
Java源文件
- 如果源文件中有多个类,那么只能有一个类是public类
- 如果有一个类是public类,那么源文件的名字必须与这个类的名字完全相同,拓展名为.java
- 如果源文件没有public类,那么源文件的名字只要和某个类的名字相同,并且拓展名为.java就行
基本数据类型和数组
标识符
- 用来标识类名、变量名、方法名、类型名、数组名及文件名的有效字符序列
- 语法规则
- 标识符由字母、数字、下划线和美元符号$组成,长度不受限制
- 不能以数字开头
- 不能是关键字
- 不能是true、false和null(尽管true、false和null不是关键字)
关键字
关键字是具有特定用途或被赋予特定意义的一些单词
基本数据类型
- 注意
- 字符类型的数据用单引号”界定
- 单精度浮点型 float 数据的常量后面必须更后缀 f 和 F
- 双精度浮点型 double 数据的常量后面必须更后缀 d 和 D
- 类型转换
byte short chat int long float double
- 当级别低的变量赋值给级别高的变量时,系统自动完成数据类型的转换
- 当级别高的变量赋值给级别低的变量时,必须使用类型转换(强制类型转换)
输入、输出基本数据
-
输入
Scanner reader = new Scanner(System.in);
如果输入带空格的字符串时使用nextLine()方法 -
输出
- System,out,print()和System.out.println()可输出串值、表达式值
- 允许使用并置符号+将变量、表达式或一个常数值与一个字符串并置一起输出
- 不可以出现回车,不然无法完成编译
数组
- 一维数组
数组元素类型 数组名[]
数组元素类型[] 数组名 - 二维数组
数据元素类型 数组名[][]
数据元素类型[][] 数组名 - 为数组分配元素
数组名 = new 数组元素类型[数组元素个数] - length的使用
数组名.length
运算符、表达式和语句
算术运算符与算术表达式
- 加减运算符
加减运算符+,-是二目运算符,即连接两个操作元得运算符。加减运算符得结合方向是从左到右。 - 乘、除和求余运算符
乘、除和求余运算符*、/、%是二目运算符,结合方向从左到右。
用算术运算符和括号连接起来的符合Java语法规则的式子,称为算术表达式。
自增、自减运算符
自增、自减运算符++、–是单目运算符,可以放在操作元之前,也可以放在操作元之后。操作元必须是一个整型或浮点型变量,作用是使变量的值增1或减1。
- ++x(–x)表示在使用x之前,先使x的值增(减)1。
- x++(x–)表示在使用x之后,先使x的值增(减)1。
位运算符
- 按位与运算符&
同1为1,遇0则0 - 按位或运算符|
遇1则1 - 按位非运算~
0变1,1变0 - 按位异或运算符^
对应位相同为0,不同为1
aa=0,a0=a,abb=0(一个数与同一个数异或两次,结果为它本身)
语句概述
- if语句
- if语句是单条件单分支语句,即根据一个条件来控制程序执行的流程。
- 语法格式
if(表达式){
若干语句
} - 小括号()内的表达式的值必须是boolean类型
- if-else语句
- if-else语句是单条件双分支语句,即根据一个条件来控制程序执行的流程
- 语法格式
if(表达式){
若干语句
}else{
若干语句
}
- if-else if-else语句
- if-else if-else语句是多条件双分支语句,即根据多个条件来控制程序执行的流程
- 语法格式
if(表达式){
若干语句
}else if{
若干语句
}
.
.
.
else{
若干语句
}
- switch开关语句
- switch语句是单条件多分支的开关语句
- 语法格式
switch(表达式){
case 常量值1:若干语句 break;
case 常量值2:若干语句 break;
.
.
.
case 常量值n:若干语句 break;
default:若干语句
} - switch语句中“表达式”的值可以为byte、short、int、char型;
- case语句中“常量值”的值可以为byte、short、int、char型,而且要互不相同;
- for循环语句
- 表达式
for(表达式1;表达式2;表达式3){
若干语句
} - for语句的执行规则
(1)计算表达式1,完成必要的初始化工作。
(2)判断表达式2的值,若表达式2的值为true,则进行(3),否则执行(4)
(3)执行循环体,然后计算表达式3,以便改变循环条件,进行(2)
(4)结束for语句执行
- while语句
- 语法格式
while(表达式){
若干语句
}
- break和continue语句
在循环语句中,如果某次循环执行了break语句,那么整个循环语句结束。如果某次循环执行了continue语句,那么本次循环结束,即不再执行本次循环中循环体中continue后面的语句,而转入进行下一次循环。 - for语句与数组
- 语法格式
for(声明循环变量:数组的名字){
……
}
类与对象
- 面向对象三大语言的三大特性
- 封装性
将数据和对数据的操作封装在一起 - 继承
子类可以继承父类的属性和行为,即继承父类所具有的数据和数据上的操作,同时又可以增添子类独有的数据和数据上的操作 - 多态
(1)操作名称的多态
即有多个操作具有相同的名字,但这些操作所接受的消息类型必须不同
(2)继承有关的多态
同一个操作被不同类型的对象调用时可能产生不同的行为
- 类
- 类是Java程序的基本要素,一个Java程序就是由若干个类所构成。类是Java语言中最重要的“数据类型”,类声明的变量被称作对象变量,简称对象。
类的定义包括两个部分:类声明和类体 - 基本格式
class 类名{
类体的内容
}
class是关键字,用来定义类 - 类声明的编程风格
(1)、如果类名使用拉丁字母,那么字母的首字母使用大写字母。
(2)类名最好容易识别、见名知义。 - 类的目的
类的目的是抽象出一类事物共有的属性和行为,并用一定的语法格式来描述所抽象出的属性和行为
- 成员变量
- 成员变量的类型
成员变量可以是Java中的任何一种数据类型 - 成员变量的有效范围
成员变量在整个类内都有效,其有效性与它在类体中书写的先后位置无关
- 方法
- 局部变量
(1)在方法体中声明的变量和方法的参数被称作局部变量
(2)和类变量不同得是,局部变量只在方法内有效,而且与其申明的位置有关
1.区分成员变量和局部变量
(1)如果局部变量的名字和成与变量的名字相同,那么成员变量被隐藏,即该成员变量在这个方法内暂时失效
(2)如果想在该方法中使用被隐藏的成员变量,必须使用关键字this - 局部变量没有默认值
成员变量有默认值,但局部变量没有默认值,因此在使用局部变量之前,必须保证局部变量有具体的值
- 构造方法与对象的创建
- 定义
构造方法是类中的一个特殊方法,当程序用类创建对象时需使用它的构造方法 - 特性
(1)方法名与类名相同
(2)没有返回值
(3)可被重载 - 无参构造方法
如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句
- 创建对象
- 总结
new运算符只能和类的构造方法进行运算,运算的最后一个结果是一个十六进制的数,这个数称作对象的引用
注:(1)对象的引用存放栈中,对象的实体(分配给对象的变量)存在堆中;(2)栈的优势是,存取速度比堆要快。缺点是,存在栈中的数据大小和生命周期必须是确定的,缺乏灵活性;(3)堆的优势是,可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
- 使用对象
- 对象操作自己的变量(体现变量的属性)
(1)对象创建之后,就有了自己的变量,即对象的实体。对象通过使用点运算符“.”(点算法符也称引用运算符或访问运算符)访问自己的变量
(2)访问格式
对象.变量 - 对象调用类中的方法(体现对象的行为)
(1)对象创建之后,可以使用点运算符“.”调用创建它的类中的方法,从而产生一定的行为(功能)
(2)调用格式
对象.方法 - 体现封装
当对象调用方法时,方法中出现的成员变量就是指分配给该对象的变量
- 对象的引用和实体
- 避免使用空对象
没有实体的对象称作空对象,空对象不能使用,即不能让一个空对象去调用方法产生行为。 - 重要结论
一个类声明的两个对象如果具有相同的引用,二者就具有完全相同的变量 - 垃圾收集
“垃圾收集”机制周期地检测某个实体是否已不再被任何对象所拥有(引用),如果发现这样的实体,就释放实体占有的内存
注:如果希望Java虚拟机立刻进行“垃圾收集”操作,可以让System类调用gc()方法
- 参数传值
- 基本类型类型参数的传值
(1)对于基本数据的参数,向该参数传递的值的级别不可以高于该参数的级别
(2)基本数据类型在传值时,传的是基本数据的副本 - 引用类型参数的传值
(1)引用数据:类、接口、数组
(2)“传值”传递的是变量中存放的“引用”,而不是变量所引用的实体
(3)如果改变参数变量所引用的实体,就会导致原变量的实体发生同样的变化 - 可变参数
(1)定义方法时参数个数可以变化
(2)必须时参数列表中的最后一个
- 对象组合
- 关联关系
一个类中使用另一个类的对象作为该类的成员变量 - 组合与复用
(1)如果一个对象a组合了对象b,那么对象a就可以委托对象b调用其方法,即对象a以组合的方式复用对象b的方法
(2)特点
a、通过组合对象来复用方法也称“黑盒”复用,因为当前对象只能委托所包含的对象调用其方法,这样一来,当前对象对所包含的对象的方法的细节(算法的细节)时一无所知的。
b、当前对象随时可以更新所包含的对象,即对象与所包含的对象属于 弱耦合关系。
注:一个类声明的两个对象如果具有相同的引用,二者就具有完全相同的变量
- 实例成员与类成员
- 声明
在声明成员变量时,用关键字static给予修饰的称作类变量,否则称为实例变量(类变量也称为static变量、静态变量)
static需要放在变量的类型前面 - 区别
(1)不同对象的实例变量互不相同
一个类通过使用new运算符可以创建多个不同的对象,这些对象将被分配不同的(成员)变量。说得准确些就是:分配给不同对象的实例变量占用的内存空间,改变其中一个对象的实例变量不会影响其他对象的实例变量
(2)所有对象共享类变量
如果类中有类变量,当使用new运算符创建多个不同的对象时,分配给这些对象的这个类变量占有相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说,对象共享类变量
(3)通过类名直接访问类变量
当Java程序执行时,类的字节码文件被加载到内存,如果该类没有创建对象,类中的实例变量不会被分配内存。但是,类中的类变量,在该类被加载到内存时就分配了相应的内存空间。即所有的对象的类变量是相同的一处内存空间,类变量的内存空间直到程序退出运行,才释放所占有的内存。
a、类变量不仅可以通过某个对象访问,也可以直接通过类名访问
b、实例变量仅可以通过对象访问,不能使用类名访问
注:类变量似乎破坏了封装性,其实不然,当对象调用实例方法时,该方法中出现的类变量也是该对象的变量,只不过这个变量和所有的的其它对象共享而已。
- 实例方法和类方法的定义
1.区别
(1)实例方法可以被类创建的任何对象调用执行
(2)类方法不仅可以被类创建的任何对象调用,也可以通过类名调用
当创建第一个对象的时候,类中的实例方法就分配了入口地址 - Arrays
- 排序
public static void sort(double a[])
public static void sort(double a[],int start,int end) - 判断参数number指定的数值是否在参数a指定的数组中
找到相同的返回(得到)该元素的索引,否则返回一个负数
public static int binarySearch(double a[],double number)
- 方法的重载
- 多态类型
功能多态:可以向功能传递不同的消息,以便让对象根据相应消息产生相应的行为。
行为多态:对象的行为通过类中的方法来体现 - 语法规则
(1)定义
一个类可以有多个方法具有相同的名字,但这些方法的参数必须不同
同一类别,方法名相同,形参列表不同(个数,类型,顺序),方法返回值可不同
注:方法的返回类型和参数名字不参与比较,如果两个方法的名字相同,即使返回类型不同,也必须报账参数不同
- this关键字
- 定义
this是Java的一个关键字,表示某个对象。this可以出现在实例方法和构造方法中,但不可以出现在类方法中。 - 在方法中使用this
(1)在构造方法中使用
代表使用该构造方法所创造的对象
(2)在实例方法中使用
代表正在调用该方法的当前对象
当实例成员变量的名字和局部变量的名字相同时,成员变量前面的“this.”和“类名.”就不可以省略
注:this不能出现在类方法中,这是因为类方法可以通过类名直接调用,这时可能还没有对象产生
- 包
- 定义
package语句作为Java源文件的第一条语句,指明该源文件定义的类所在的包,即为该源文件中声明的类指定包名。 package 包名;
如果不加package语句,则指定为缺省包或无名包
- 访问权限
- 定义
所谓访问权限,是指对象是否可以通过“.”运算符操作自己的变量或通过“.”运算符调用类中的方法。访问限制修饰符有private、protected和public。 - 权限汇总
子类与继承
- 为什么要继承
(1)、通过继承可以简化类的定义
(2)、拓展类的功能
(3)、继承是一种由已有类创建新类的机制。利用继承,可以先定义一个共有属性的一般类,根据该一般类再定义具有特殊属性的子类,子类继承一般类的属性和行为,并根据需要增加它自己的新的属性和行为。
(4)、由继承得到的类称为子类,被继承的类称为父类(超类)
(5)、在类声明中,通过使用关键字extends来定义一个类的子类 - 继承的规定
(1)、Java只支持单继承,不允许多继承
(2)、Java允许有多层继承
(3)、子类只能继承父类所有的非私有成员
(4)、在创建子类对象时,父类中的private成员变量会被分配内存
(5)、子类对象在实例化时,默认调用父类的无参构造方法 - 子类的继承性
(1)、子类和父类在同一个包中的继承性,子类自然地继承了其父类中不是private的成员变量和方法,访问权限继续保持不变
(2)、子类和父类不在同一包中的继承性,父类中的private和友好访问权限的成员变量和方法不会被子类继承(只继承public、protected), - instanceof运算符
instanceof运算符是Java独有的双目运算符,其左面的操作元是对象,右面的操作元是类,当左面的操作元是右面操作元的类或其子类创建的对象时,instanceof运算的结果是true,否则false - 成员变量的隐藏
(1)、所声明的成员的名字和从父类继承来的成员变量的名字相同(声明的类型可以不同),在这种情况下,子类就会隐藏所继承的成员变量
(2)子类隐藏继承的成员变量的特点
a、子类对象以及子类自己定义的方法操作与父类同名的成员变量是指子类重新声明的这个成员变量
b、子类对象仍然可以可以调用从父类继承的方法操作被子类隐藏的成员变量,也就是说,子类继承的方法所操作的成员变量一定是被子类继承或隐藏的成员变量 - 方法重写
- 定义
子类通过重写可以隐藏已继承的方法(方法重写称为方法覆盖) - 语法规则
所谓方法重写,是指子类中定义一个方法,这个方法的类型和父类的方法的类型一致或是父类的方法的类型的子类型,并且这个方法的名字、参数个数、参数类型和父类方法完全相同,返回值类型也相同 - 重写的目的
子类通过方法的重写可以隐藏继承的方法,子类通过方法的重写可以帮父类的状态和行为改变为自身的状态和行为
- Object类
Object类是所有类的祖先类 - super关键字
- 定义
子类一旦隐藏了继承的方法,那么子类创建的对象就不能调用被隐藏的方法,该方法的调用由关键字super负责。如果在子类中想使用被子类隐藏的成员变量或方法,就需要使用关键字super - 调用格式
(1)、调用隐藏的成员变量 super.成员变量
(2)、调用隐藏的方法 super.方法名() - 使用super调用父类的构造方法
(1)、当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就先调用父类的不带参数的构造方法。
(2)、super(); 调用父类某个构造方法(无参的构造方法)
super.方法名(); 调用特定的方法
- final关键字
- 定义
final关键字可以修饰类、成员变量和方法中的局部变量及参数 - final类
final类不能被继承,即不能有子类 - final方法
如果用final修饰父类中的一个方法,那么这个方法不允许子类重写,也就说,不允许子类隐藏可以继承的final方法(老老实实继承,不许做任何篡改) - 常量
如果成员变量或局部变量被修饰为final,那么它就是常量,在声明常量时,必须指定该常量的值。值要么在定义时就给,要么在构造方法中给。
如果方法中的参数被final修饰,不能被修改
- 对象的上转型对象
- 定义
父类声明,子类实例化 - 方式
(1)、子类对象向父类对象转换(向上)
自动转型 (父类对象 = 子类对象)
(2)、父类对象向子类对象转换(向下)
强制转型 (子类对象 = (子类)父类对象【上转型对象】) - 特点
(1)、上转型对象不能操作子类新增的成员变量(失掉了这部分属性),不能调用子类新增的方法(失掉了一部分行为)
(2)、上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。如果子类重写了父类的某个实例方法后,当对象的上转型对象调用这个实例方法时一定是调用了子类重写的实例方法。 - 注意
(1)、不要将父类创建的对象和子类对象的上转型对象混淆。
(2)、可以将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类对象多有的属性和功能
(3)、不可以将父类创建的对象的引用赋值给子类声明的对象(不能说“人是美国人”)
(4)、如果子类重写了父类的静态方法,那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法
- abstract类和abstract方法
- 定义
(1)、用关键字abstract修饰的类称为abstract类(抽象类);用关键字abstract修饰的方法称为abstract方法(抽象方法),无方法体,无“{}” - 特点
(1)、abstract类中可以有abstract方法
和普通类(非abstract类)相比,abstract类中可以有abstract方法(非abstract类中不可以有abstract方法)也可以有abstract方法
abstract类里也可以没有abstract方法
(2)、abstract类不能用new运算符创建对象,不能实例化
(3)、abstract类的子类:必须重写父类所有的抽象方法
(4)、abstract类的对象作上转型对象
- 开-闭原则
对类的修改是封闭的,对类的扩展时丰富的
接口与实现
- 接口
- 接口声明
定义接口包含接口声明和接口体,定义接口时使用关键字interface来声明自己是一个接口
interface 接口的名字 - 接口体
接口体中包含常量的声明(没有变量)和抽象方法两部分。接口体中只有抽象方法,没有普通方法,而且接口体中所有的常量的访问权限一定都是public,而且是static常量
(1)、常量:public static final 全局静态常量
(2)、方法:public abstract 抽象
关键词可以部分省也可以全部省 - 实现接口
(1)、类实现接口
在Java语言中,接口由类来实现以便使用接口中的方法。一个类需要在类申明中使用关键字implements声明该类实现一个或多个接口
(2)、重写类中的方法
如果一个非抽象实现了某个接口,那么这个类必须重写这个接口中的所有方法。方法的访问权限一定要明显地用public来修饰
注:一个类声明实现一个接口,但没有重写接口中的所有方法,那么这个类必须是抽象类,也就是说,抽象类既可以重写接口中的方法,也可以直接拥有接口中的方法
(3)、接口的细节实现
a、程序可以用接口名访问接口中的常量,但是如果一个类实现了接口,那么该类可以直接在类体中使用该接口中的常量。
b、public接口可以被任何一个类实现;如果一个接口不加public修饰,就称作友好接口,友好接口可以被与该接口在同一个包中的类实现。
c、如果父类实现了某个接口,那么子类也就自然实现了该接口,子类不必再显示地使用关键字implements声明实现这个接口。
d、接口也可以被继承,即可以通过关键字extends声明一个接口是另一个接口的子接口。由于接口中的方法和常量都是public的,子接口将继承父接口中的全部方法和常量。
注:Java提供的接口都在相应的包中,通过import语句不仅可以引入包中的类,也可以引入包中的接口
- 接口回调
- 定义
可以把实现某一接口的类创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口方法。
接口回调无法调用实现类新增的方法;接口声明,实现类实例化
- 理解接口
- 接口使用关键点
(1)、接口可以抽象出重要的行为标准,该行为标准用抽象方法来表示
(2)、可以把实现接口的类的对象的引用赋值给接口变量,该接口变量可以调用被该类实现的接口方法,即体现该类根据接口里的行为标准给出具体行为
- 接口参数
如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递该接口参数,那么接口参数就可以回调类实现的接口方法 - abstract类与接口的比较
(1)、abstract类和接口都可以有abstract方法
(2)、接口中只可以有常量,不能有变量;而abstract类既可以有常量,可以有变量
(3)、abstract类中也可以有非abstract方法,接口不可以
内部类与异常类
- 内部类
- 定义
Java支持在一个类中定义另一个类,这样的类称作内部类,而包含内部类的类称为内部类的外嵌类 - 内部类与外嵌类之间的关系
(1)、内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法
(2)、内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员
(3)、内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象
- 匿名类
- 定义
匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明对象,但却可以直接用匿名类创建一个对象
new Bank(){
匿名类的类体
}; - 特点
(1)、匿名类可以继承父类的方法也可以重写父类的方法
(2)、使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定是内部类
(3)、匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和static方法
(4)、由于匿名类是一个子类,但没有类名,所以在用匿名类创建对象时,要直接用父类的构造方法 - 和接口有关的匿名类
Java允许直接用接口名和一个类体创建一个匿名对象
- 异常类
- 定义
异常就是程序运行时可能出现的一些错误,异常处理将会改变程序的控制流程,让程序有机会对错误做出处理 - 分类
a、所有异常的父类:Throwable
b、Error:JVM系统内部错误、资源耗尽等严重错误
c、Exception:其它因编程错误或偶然的外在因素导致的一般性问题
(程序员能处理Exception,无法处理Error) - try-catch语句
Java使用try-catch语句来处理异常,将可能出现的异常操作放在try-catch语句的try部分,一旦try部分抛出异常对象,或调用某个可能抛出异常对象的方法,并且该方法抛出了异常对象,那么try部分将立刻结束执行,转向执行相应的catch语句。所以程序可以将发生异常后的处理放在catch部分。 - Exception类常用的三个函数
(1)、getMessage():输出错误性质
(2)、toString():给出异常的类型和性质
(3)、printStackTrace():指出异常的类型和性质,堆栈层次及出现在程序中的位置 - 自定义异常类:需要继承Exception类
一个方法在声明时可以使用throws关键字声明要产生的若干个异常,并在该方法的方法体中具体给出产生异常的操作,即用相应的异常类创建对象,并使用throw关键字抛出该异常对象,导致该方法结束执行
- 断言
断言语句在调试代码阶段非常有用,断言语句一般用于程序不准备通过捕获异常来处理错误。
- 断言语句的语法格式
使用关键字assert声明一条断言语句
(1)、assert booleanExpression;
(2)、assert booleanExpression::messageException; - 启用与关闭断言语句
当使用Java解释器直接运行应用程序时,默认地关闭断言语句,在调试程序时可以使用-ea启用断言语句
java -ea mainClass
- finally
- 带finally子语句的try-catch语句
try{} //此处是可能出现异常的代码
catch(ExceptionSubClass e){} //如果发生异常处理代码
finally{} //肯定被执行的代码 - 两种特殊情况
(1)、如果在try-catch语句中执行了return语句,那么finally子语句仍然会被执行
(2)、try-catch语句中执行了程序退出代码,即执行System.exit(0)【退出JVM虚拟机】;则不执行finally子语句(当然包括其后的所有语句)