类加载
加载过程:加载,验证,准备,解析,初始化,过程交叉执行,例如先验证class字节流是否符合规范,属于验证,验证通过后再加载到方法区,形成一种特殊的数据结构,这是属于加载,然后对数据结构验证是否符合Java语言规范,验证语义是否会对虚拟机造成危害,验证是否指针地址等等。此处的加载和验证交叉进行。其它过程也存在交叉。
准备阶段,为静态变量开辟空间保存,赋值初值0,false,null。
解析,字面量和字符引用改为直接引用。
初始化,调用构造函数,首先执行父类的构造函数,因为在子类的构造函数中第一行必须调用父类的构造函数,即使不写,编译器也会调用父类的无参构造函数,如果没有则会编译错误。
实例变量是属于对象,类变量是属于类,意思就是static修饰的变量属于类变量。实例变量和类变量都会被赋予初始值,即0,false,null。
查看字节码指令,通过jdk指令,javap -v xxx.class。
static{}和{}的区别,static作用于静态代码块,即clinit()函数,{}会被编译到构造函数,也就是init()函数;
父类–静态变量
父类–静态初始化块
子类–静态变量
子类–静态初始化块
父类–变量
父类–初始化块
父类–构造器
子类–变量
子类–初始化块
子类–构造器
初始化块可以放在变量定义之前,并且给变量赋值,但最终的值是定义在后面的直接赋值,如果初始化块放在变量定义的后面,最终的值是初始化块赋予的值。但如果有打印语句,可以证明初始化代码块无论放在前面还是后面,都是先执行初始化块,再执行的构造函数。
strictfp精确浮点 strict float point缩写,修饰类,接口,方法,浮点运算更加精确,不同平台运行结果相同。
transient 序列化时候不被序列化