本篇文章给大家带来的内容是Java从虚拟机角度分析什么是类的实例化顺序。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助。
1、首先展示一下实例代码(Son.java & Father.java)
public class Father { public static int a=10;//父类的静态变量 static{//父类的静态代码块 a=20; } {//父类的构造代码块 a=30; } public Father() {//父类的构造方法 a=40; } }
public class Son extends Father{ public static int s=10;//子类的静态变量 public int k=20;//子类的实例变量 static{//子类的静态代码块 s=20; } {//子类的构造代码块 s=30; } public Son() {//子类的构造函数 s=40; } {//子类的构造代码块 s=50; } }
2、将son.java文件编译为son.class文件,然后使用javap反编译查看Son的字节码指令来分析Son的加载顺序,更利于理解(javap -v -c Son > p.txt)。
3、执行代码"new Son();"后,分析类的加载顺序。
下面的static{};为
static {}; descriptor: ()V flags: ACC_STATIC Code: stack=1, locals=0, args_size=0 0: bipush 10 2: putstatic #11 // Field s:I--------------------------顺序执行静态变量的赋值 5: bipush 20 7: putstatic #11 // Field s:I--------------------------顺序执行静态代码块 10: return
public packet1020.Son(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #16 // Method packet1020/Father."<init>":()V--------------------执行父类的<init>函数(顺序不变,第一个) 4: aload_0 5: bipush 20 7: putfield #18 // Field k:I------------------------------------------------按顺序收集实例变量赋值 10: bipush 30 12: putstatic #11 // Field s:I------------------------------------------------按顺序收集构造代码块 15: bipush 50 17: putstatic #11 // Field s:I------------------------------------------------按顺序收集构造代码块 20: bipush 40 22: putstatic #11 // Field s:I------------------------------------------------最后执行自己的构造函数代码(顺序不变,最后一个) 25: return
开始分析:
1.触发类的加载,在初始化阶段,先执行父类
2.代码中执行了构造函数,所以执行
结论:
1.父类中顺序执行静态变量赋值,静态代码块
2.子类中顺序执行静态变量赋值,静态代码块
3.父类中顺序执行实例变量赋值,构造代码块
4.父类构造函数
5.子类中顺序执行实例变量赋值,构造代码块
6.子类构造函数
名字解释:摘抄自周志明老师的《深入理解Java虚拟机:JVM高级特性与最佳实践》
1.有且只有4中情况下必须对类进行初始化(执行
2.
3.
构造代码块执行顺序先于构造函数
<init>(){ 1.调用父类<init>方法 2.顺序执行实例变量的赋值操作和构造代码块 3.程序员自己的构造函数方法代码 }
总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。更多相关教程请访问Java视频教程,java开发图文教程,bootstrap视频教程!
Atas ialah kandungan terperinci Java从虚拟机角度分析什么是类的实例化顺序. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!