首页 > 编程语言 >深入 JVM 字节码,解析类加载、链接、初始化、创建对象、对象初始化、程序执行的流程

深入 JVM 字节码,解析类加载、链接、初始化、创建对象、对象初始化、程序执行的流程

时间:2022-12-29 17:07:02浏览次数:61  
标签:初始化 超类 代码 创建对象 程序执行 static JVM 加载


概述:

本文通过引入一道面试题来解析类加载、类链接、类初始化过程,以及创建创建对象、对象初始化和程序执行的过程。

你将收获:

1、精通类加载、类链接、类初始化过程

2、深入源码层面了解类初始化、对象初始化的原理

3、额外的收获。(- 解不出题的人收获)

目录:

1、面试题

2、类加载、类链接、类初始化的知识点

3、深入字节码源码,解析面试题

4、答疑解惑

5、全文知识点总结

 

话不多说,开干! :说说下面程序的输出是什么?

深入 JVM 字节码,解析类加载、链接、初始化、创建对象、对象初始化、程序执行的流程_java

(答案在文末),如果你有疑问,尝试看看下文。

在解释程序前,我们先铺垫类加载、链接、初始化、创建对象、对象初始化的知识点,简单举例说一下程序是怎么运行起来的,这样更有利于大家解题:

深入 JVM 字节码,解析类加载、链接、初始化、创建对象、对象初始化、程序执行的流程_初始化_02

程序执行的流程:

1、输入“java Test”命令

    JVM企图运行Test类的main方法,发现Test类没加载到内存中

2、JVM加载、链接、初始化Test类。

    这里加载、链接两个概念不明白不要紧,不影响我们解题。但要说说“类初始化”的概念,因为从类初始化这步开始涉及            java代码的执行

    初始化概念:初始化是指执行类或接口的初始化方法<clinit>(<java虚拟机规范>的描述)。这里的<clinit>方法,大家是         虚拟机自己生成的一个方法,在初始化阶段被JVM执行,后面会看到。

    初始化规则:static变量初始化代码和static代码块中的代码,在类初始化这步按照在代码中书写的顺序被执行。类初始化         前,其直接超类已经被初始化,直接超类的直接超类也需如此(<java虚拟机规范>的描述)。 

3、执行Test类的main方法

    前面知识的铺垫,还是有点抽象,那么我根据javac编译后的字节码翻译一下代码,这样就会有个具体的直观认识:

深入 JVM 字节码,解析类加载、链接、初始化、创建对象、对象初始化、程序执行的流程_类初始化_03

答疑解惑:

其实很多人最大的疑问是在“ static Son son = new Son();”这行代码,这里不用纠结,虚拟机规范并没有规定类初始化阶段    不能执行创建对象的逻辑。说白了,类初始化就是JVM执行代码的过程,没什么特别的。

看完上文的解释,大家是不是清楚了这里程序的输出呢! 

全文知识点总结:

1、javac编译实现:

    javac编译器生成一个<clinit>方法,把“静态变量的初始化语句”和“static代码块语句”按照代码中的顺序编译到<clinit>方法中;

    javac编译器把“实例变量的初始化语句”和“实例代码块的语句”按照代码中的顺序编译到了构造方法中;

    以上两点从翻译的代码中可以看出来。

2、类初始化:

    类初始化前,其直接超类已经被初始化,直接超类的直接超类也需如此。即javac生成的 <clinit>方法由JVM在“类初始化阶段”调用,调用类的<clinit>方法前,必须先调用父类的<clinit>方法。

3、创建对象、对象初始化 

    执行构造方法在堆中创建一个对象。在没有显示调用父类构造方法情况下,所有构造方法的首行都会隐含调用父类的无参构造方法。

更详细解析参照:​​http://gitbook.cn/gitchat/activity/5db3f2c857529f30fbf2bac4​



程序输出:

4father init block
6Father constructor
1son init block
3son constructor
5Father static block
2Son static block
4father init block
6Father constructor
1son init block
3son constructor
---end---

 

标签:初始化,超类,代码,创建对象,程序执行,static,JVM,加载
From: https://blog.51cto.com/u_14724733/5978503

相关文章