当我们在调用Java命令运行一个Java程序时,该命令会启动一条Java虚拟机的进程。

   当程序主动使用某个类时:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

      如果该类还未被加载到内存中,jvm会通过加载,连接,初始化来对类进行初始化,通常把这3个步骤统称为类的加载或者类的初始化,

      类的加载:

        类的加载是指将编译好的类的class文件加载到内存中,随后,系统会创建一个Java.lang.Class对象,也就是说,任何一个类的class文件被加载到内存后,系统都会为之创建一个Java.lang.Class对象。

        上述的加载过程是由类加载器来完成的。类加载器通常是由jvm来提供的,jvm提供的这些类加载器称为系统类加载器,除此之外,可以通过继承ClassLoader类来创建自己的类加载器。

        类加载器加载的文件有:

          项目本地的Java程序编译后的class类文件

          项目引用的jar包中的class类文件

          项目中通过网络加载的class文件

    类的连接:

      当类被加载后,会生成一个对应的class对象,接着会进入连接阶段,连接阶段负责把类的二进制数据合并到JRE中。

        1.验证:验证被加载的类中是否有正确的内部结构,并和其他类协调一致

          验证阶段:验证类是否遵从Java类文件的固定格式;会进行语义检查;会确保相互应用的类之间协调一致,比如Work类中有个gotowork的方法,方法中调用了car.run()的方法,Java虚拟机在验证Work类的同时,会检查方法区内是否存在Car类的run方法,如果不存在,会抛异常。

        2.准备:为静态属性分布内存,并设置默认初始值

          为静态属性分布内存空间;

          设置默认初始值:

              Java的类是怎么执行的 随笔 第1张

          Java虚拟机会给int类型的静态变量a分配4个字节的内存空间,并设置初始值0,给Long类型的静态变量b分配8个字节的空间,设置初始值为0,当类初始化时,才会将a的值改为1,b改为2

        3.解析:将类中的二进制数据中的符号引用替换为直接引用

           Java虚拟机会将Work类中gotowork()方法中调用的car.run方法的描述改为指针

          Java的类是怎么执行的 随笔 第2张

 

     类的初始化:

           当一个类加载,连接完成后,就会对类进行初始化。类的初始化大体步骤为: 先将类的所有的成员变量进行初始化,待类的成员变量初始化完成后,会调用类的构造方法来构造对象。

          类的初始化步骤:

             1,当类还没有被加载,连接时,先进行类的加载和连接。

             2,如果类的直接父类还没有被初始化,先初始化直接父类。

             3,按照类中的初始化语句依次执行初始化语句。

                执行初始化语句的顺序:先父后子,静态全完成,再分父与子。父类完成后,再来构造子。

                 1. 父类(静态成员变量)

                 2. 父类(静态代码块)

                 3. 子类(静态成员变量)

                 4. 子类(静态代码块)

                 5. 父类(普通成员变量)

                 6. 父类(普通代码块)

                 7. 父类(构造函数)

                 8. 子类(普通成员变量)

                 9. 子类(普通代码块)

                 10. 子类(构造函数)

            类的加载或初始化时机:

                1.创建类的实例(就是去new一个对象时)

                2.调用某个类的静态方法时(直接用类名.静态方法)

                3.访问某个类或者接口的静态属性时(如果这个静态属性被final修饰,并且编译时值确定,则调用该静态属性时,此类不会被初始化)

                4.使用反射机制来强制创建某个类或者接口对应的Java.lang.Class对象(Class.forName("Car"))

                5.初始化某个类的子类(初始化一个类时,他的所有父类都会被实例化)

                6.直接使用Java.exe命令来运行某个主类

    

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄