本文章是在韩顺平老师的Java反射专题学习的过程中记录,菜鸟学习笔记,如果有错还请赐教。
我们都知道Java文件是由Java虚拟机编译运行,其中的详细过程如下图
Java源码在执行javac命令后编译为class文件,在class文件的头部会有cofebabe标志(Java之父高斯林为了纪念他最爱去的咖啡馆)。
加载阶段:JVM将字节码文件转化为二进制并存放于方法区(Java8版本以后,是用元空间来实现的方法区,在Java8之前的版本,则是用永久代实现的方法区)。
连接阶段由分为三个阶段,分别为验证、准备、解析
- 验证:验证class文件的内容是否会危害虚拟机安全,class文件开头是
否是0xcafebabe,元数据验证、字节码验证和符号引用验证(可以使用-Xverify:none关闭大部分类验证措施,缩短虚拟机的类加载时间)。 - 准备:从方法区中获取字节码的二进制文件,并在堆中为类和类变量分配内存,为类常量分配内存的同时赋值。
- 解析:虚拟机将常量池的符号引用替换为直接引用。
初始化,到这一步才开始是Java程序员写的业务代码的执行。在加载类的过程中,主要执行两个本地方法<clinit>和<init>。
<clinit>方法执行的内容包括静态类变量显式赋值代码和静态代码块,从上往下执行,该方法只执行一次。在<clinit>方法执行完毕后,开始执行<init>方法。
<init>方法可能有多个重载,有几个构造器就有几个<init>方法。<init>方法包括非静态变量显式赋值代码和非静态代码块,以及对应构造器代码,执行顺序为从上到下,构造器代码最后执行。每次创建实例对象时,其实就是在执行其<init>方法,<init>方法的首行是super()或super(实参),跟构造器一样,对应父类的<init>方法。