1.类的加载阶段
类的加载阶段就是 类加载器根据类的全限定名 将java文件转换为字节码文件,当把类转换为字节码文件之后,会生成个instanceKlass文件,并放在方法区中,它保存了类的所有信息,同时还会在堆中生成一个java.lang.class文件和instanceKlass所关联,原因是instanceKlass是c++写的,java不能直接调用,所以关联起来间接调用,这就是类的加载阶段
2.类的连接阶段
类的连接阶段,分为验证,准备,解析三个步骤,验证阶段主要是看字节码文件是否符合jvm的编码规范,准备阶段是给静态变量符初始值,有两种情况,例如private static int a =1;此时在堆中会给a赋值为0,如果是final修饰的就会直接把最终值赋给变量。解析阶段就是将常量池的符合引用换为直接引用
3.类的初始化
触发初始化的情况
不触发初始化的情况
分析这个代码题根据以上知识,当执行main方法触发初始化,优先执行静态代码块,然后此时打印DA,然后new 一个对象会触发初始化,此时打印CBCB
最终结果DACBCB
先执行main方法触发初始化,没有静态代码块及静态变量此时没有变化,newB02,这是个子类对象,当new子类对象时会先执行父类的初始化,此时a=1,再执行子类初始化 a=2
2.如果没有new B02() 直接调用静态变量,这个静态变量是在父类中声明的,所以此时a=1
通过用jclasslib观察方法里面没有clinit 当触发类的初始化会有个clinit ,也就是class init
所以结果是不会初始化
可以看到还是没有clinit 没有初始化 原因应该是 直接访问的这个final修饰的静态变量,已经在类的准备阶段赋完值了,所以会先执行static代码块,再执行1