反编译指令:
javap -verbose
数据类型
基本类型
byte/8
char/16
short/16
int/32
float/32
long/64
double/64
boolean/~
包装类型
Integer.valueOf(2)
X.intValue()
装箱和拆箱, AutoBoxing and Unboxing
String
概览
- final类 不可被继承 (包装类都不能被继承)
- JAVA8 内部使用char数组存储数据
- JAVA9 开始改用byte数组存储字符串 用coder来标示使用哪种编码
- byte数组是final的, String内部也没有改变的方法, 因此可以保证String不可变
- 不可变的好处
可以缓存hash值
可以使得String Pool得以实现
安全性
线程安全
String, StringBuffer, StringBuilder
- string 不可变,线程安全
- StringBuilder可变,不是线程安全的
- StringBuffer可变,是线程安全的,内部使用synchronised进行同步
String Pool和intern()
- intern()返回string在StringPool中的引用
- StringPool存在JVM堆中
运算
参数传递
Java的参数是以值传递的形式传入方法中,而不是引用传递
隐式向下转型
Java不支持精度降低的隐式向下转型
隐式类型转换
使用+= 或者++运算可以实现隐式类型转换
Switch
从JAVA7开始支持 String,但是不支持 long
int 是肯定支持啦
关键字
final
- 数据
- 声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。
- 对于基本类型,final 使数值不变;
- 对于引用类型,final 使不能引用其它对象,但是被引用的对象本身是可以修改的。
- 方法
- 声明方法不能被子类重写。
- private 方法隐式地被指定为 final, 如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法。
- 类
- 声明类不允许被继承
static
- 静态变量
- 又称类变量,属于该类,类的所有实例共享,在内存中只存在一份,通过类名来访问
- 静态方法
- 在类加载的时候就存在了,不依赖任何实例,所以必须有实现,不能是抽象方法
- 静态方法只能访问所属类的静态变量和静态方法
- 静态内部类
初始化顺序 父类(静态变量、静态语句块) 子类(静态变量、静态语句块) 父类(实例变量、普通语句块) 父类(构造函数) 子类(实例变量、普通语句块) 子类(构造函数)
Object的方法
- equal
- == 判断地址
- hashcode
- clone
- 必须实现接口 cloneable
- object 的 protected 必须重写才能调用
浅拷贝和深拷贝之分
- 浅拷贝复制一个对象引用相同地址
- 深拷贝复制一个对象引用不同地址
- clone的替代方案是创建克隆构造函数或者拷贝工厂
继承
访问权限, 封装
三个访问权限修饰符:private、protected 以及 public,如果不加,默认protected
抽象类与接口
- 抽象类
- 有抽象方法必然是抽象类, 可以有非抽象方法
- 抽象类不能被实例化只能被继承
- 接口
- 接口从Java8开始,可以有方法实现
- 接口的成员默认都是public的,并且不允许定义为private或者protected
- 接口的字段默认都是static和final的
- 比较
- 一个类可以实现多个接口,但是不能继承多个类
- 接口的字段只能是static和final类型的, 抽象类无限制
- 接口的成员只能是public的,而抽象类的成员可以有很多种访问权限
- 使用选择
- 使用接口:
- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法;
- 需要使用多重继承。
- 使用抽象类:
- 需要在几个相关的类中共享代码。
- 需要能控制继承来的成员的访问权限,而不是都为 public。
- 需要继承非静态和非常量字段。
- 在很多情况下,接口优先于抽象类。因为接口没有抽象类严格的类层次结构要求,可以灵活地为一个类添加行为。并且从 Java 8 开始,接口也可以有默认的方法实现,使得修改接口的成本也变的很低。
- super调用父类
- 使用接口:
多态: 重写和重载
- 重写(Override)
- 存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法。
- 为了满足里式替换原则,重写有以下三个限制:
- 子类方法的访问权限必须大于等于父类方法;
- 子类方法的返回类型必须是父类方法返回类型或为其子类型。
- 子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型。
- 重载(Overload)
- 存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。
- 应该注意的是,返回值不同,其它都相同不算是重载。
- 使用
@Override
注解,可以让编译器帮忙检查是否满足上面的三个限制条件