1.Java 8个基本类型的包装类
为了解决8种基本类型的变量不能变成Object类型变量使用的问题,Java提供了包装类的概念:
JDK 1.5提供自动装箱和自动拆箱功能,自动装箱就是把一个基本类型变量直接赋给对应的包装类变量;自动拆箱与之相反。(两者对象类型要一致才可以)
例如:Integer a = 5; //直接把一个基本类型变量赋给Integer对象
反之,int b = a; //直接把Integer对象赋给int类型变量
特别情形:在自动装箱时,如int类型的数值自动装箱成Integer实例后,整数范围必须在-128~127之间,否则会出现溢出。
2.系统输出一个对象的处理方式
如:
Person p = new Person();
System.out.println(p); //输出:Person@15db972
与System.out.println(p.toString())结果一致,toString()方法是Object类里的一个实例方法,用于输出该对象具有的状态信息,即“类名+@+hashCode”,程序员可以重写toString()方法。
3.==和equals()方法
对于两个引用类型变量,只有它们指向同一个对象时,==判断才会返回true。如:
String str1 = new String(“hello”);
String str2 = new String(“hello”);
System.out.println(str1==str2); //输出false;
因为它们分别指向两个通过new关键字创建的String对象,str1与str2两个变量不相等。
equals()方法是Object类提供的一个实例方法,其用法与==相同,也可以重写equals()方法。
String已经重写了Object类提供的equals()方法,其判断标准是:只要两个字符串所包含的字符序列相同,通过equals()比较返回true,否则返回false。
4.类成员
Java类里只包含成员变量、方法、构造器、初始化块、内部类(包括接口和枚举)5种成员。
(1)单例类
如果一个类始终只能创建一个实例,则这个类被称为单例类。
(2)final修饰符
final变量获得初始值之后不能被重复赋值;
final修饰的成员变量必须由程序员显式指定初始值;
final成员变量在初始化之前不能被直接访问,但可以通过方法来访问。(尽量在初始化之前不访问)
由于final修饰符的作用,也可将其视为定义“宏变量”。
final修饰的方法不可以被重写,但可以被重载;
final修饰的类不可以有子类(不支持继承)。
(3)抽象类
规则如下:
抽象类和抽象方法必须使用abstract修饰(成员变量和构造器不能用abstarct修饰);
抽象类不能被实例化,无法使用new关键字来创建实例;
抽象类的构造器不能用于创建实例,主要用于被其子类调用(被当作父类被其它子类继承,也只能被继承)。子类必须实现抽象类里的所有抽象方法。
作用:为多个子类提供模板的通用方法,抽象方法推迟到子类实现。
5.接口
不再使用class关键字,而是使用interface关键字。接口里定义的方法只能是抽象方法、类方法、默认方法以及私有方法,系统将自动为普通方法增加abstract修饰符且为了子类实现抽象方法。
普通方法只能是public的抽象方法;
成员变量默认使用public static final修饰,不可修改。
使用接口:
[修饰符] class 类名 extends 父类 implements 接口1,接口2,…
接口和抽象类的区别:
6.面向接口编程
(1)简单工厂模式
利用接口实现系统与操作分开,即使操作更新(重构),改动也很小
(2)命令模式
将类和具体“处理行为”分离,接口不进行真正处理。
7.内部类
特点:
- 内部类隐藏在外部类之内,不允许同一个包中的其它类访问该类。
- 内部类成员可以直接访问外部类的私有数据。反之不可以。
- 非静态内部类不能拥有静态成员(静态方法、静态成员变量、静态初始化块)
分类:
(1)静态内部类:与使用普通类无区别
当在非静态内部类访问某个变量时,检索顺序是:方法->内部类->外部类
(2)静态内部类:static修饰
静态内部类是外部类的一个静态成员,但外部类不能直接访问静态内部类的成员,可以使用静态内部类的类名作为调用者访问或者使用静态内部类对象(即new)来访问。
(3)局部内部类:将内部类定义在方法里(很少使用)
(4)匿名内部类:必须继承一个父类或实现一个接口(均只限一个)
匿名内部类不能是抽象类,不能定义构造器,但可以定义初始化块。
非静态内部类的构造器必须使用外部类对象来调用。而静态内部类只需使用外部类即可调用构造器。
定义匿名内部类无须class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。
8.Java 8 新增的Lambda表达式
Lambda表达式支持将代码块作为方法参数,主要作用就是代替匿名内部类的烦琐语法。由形参列表、箭头(->)和代码块三部分组成。
Lambda表达式的目标类型必须是函数式接口,即只包含一个抽象方法的接口。
Lambda表达式与匿名内部类的主要区别:
- 匿名内部类可以为任意接口创建实例(接口不限抽象方法);而Lambda表达式只能为函数式接口创建实例。
- 匿名内部类实现的抽象方法的方法体允许调用接口中定义的默认方法;但Lambda表达式的代码块不允许调用接口中定义的默认方法。
9.枚举类
使用enum关键字定义枚举类,默认继承java.lang.Enum类(不是Object类)。
特点:
- 枚举类不能派生子类(非抽象的枚举类默认使用final修饰)
- 枚举类的构造器只能使用private访问修饰符。
- 枚举类的所有实例必须在枚举类的第一行显式列出。
实现接口的枚举类与普通类使用相同。
10.对象与垃圾回收
对象在堆内存中的三种状态:
可达状态、可恢复状态、不可达状态
(1)强制垃圾回收的两种方式:
调用System类的gc()静态方法:System.gc()
调用Runtime对象的gc()实例方法:Runtime.getRuntime().gc()
(2)finalize方法:在没有明确指定清理资源的情况下,Java提供了默认机制来清理该对象的资源,即finalize()方法。(属于Object类里的实例对象)任何Java类都可以重写finalize()方法。当JVM执行finalize()方法时出现异常时,垃圾回收机制不会报告异常。