类的生命周期复盘

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

猜你喜欢

转载自blog.csdn.net/qq_62646841/article/details/138290843