怎么认识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."":()V--------------------执行父类的 函数(顺序不变,第一个) 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.
构造代码块执行顺序先于构造函数
(){ 1.调用父类 方法 2.顺序执行实例变量的赋值操作和构造代码块 3.程序员自己的构造函数方法代码 }
看完上述内容,你们掌握怎么认识Java从虚拟机角度分析类的实例化顺序的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!