深入理解java虚拟机-第四章:虚拟机类加载机制

一、类的生命周期

    a)  生命周期:类从被加载到虚拟机中开始,到卸载出虚拟机为止。

    b)  各个阶段

    深入理解java虚拟机-第四章:虚拟机类加载机制_第1张图片

         注:上图是类加载的各个阶段,绿框这5个阶段顺序是确定的,类加载的过程必须按照这个阶段开始(注意是开始,不是进行,各个阶段在进行时存在相互交叉混合的情况)

  

       1)加载 :  虚拟机没有强制约束何时开始。

         在此阶段,虚拟机完成三件事:

  • 通过一个类的全限定名来获取定义此类的二进制字节流。
  • 将这个流所代表的静态存储结构转变为 方法区的运行时 数据结构。
  • 在java堆中生成一个代表此类的java.lang.class对象,作为方法区访问此对象的入口。      

        

       2)连接

  • 验证:确保Class文件中的字节流所包含的信息是安全的。
  • 准备:正式为类变量分配内存并设置类变量初始值。
  • 解析:虚拟机将常量池中的符号引用改为直接引用。
  深入理解java虚拟机-第四章:虚拟机类加载机制_第2张图片
             
   

       3)初始化:真正开始执行类中定义的java代码。

          在准备阶段已经赋予变量的初始值,将在这个阶段进行实际赋值。

          有且只有4中情况需要对类进行初始化(加载、验证和准备阶段需要在此之前开始)--主动引用

  • 使用new关键字实例化对象的时候;调用类的静态方法的时候;读取或设置一个类的静态属性的时候(被final修饰和已经放入常量池的除外)
  • 对类进行反射调用的时候
  • 对类进行初始化,但发现它继承的父类还没有初始化的时候。(接口除外)
  • 虚拟机启动,需要指定一个执行主类的时候。     
        注:以上被称为主动个引用。 

       4)使用:不多说。

       5)卸载:结束生命周期。

  • 执行Sysem.exit();方法
  • 程序正常运行结束。
  • 程序抛出异常。
  • 操作系统宕机。      
------------------以下为实例------------------------

public class SuperClass {

static{
System.out.println("super is init!");
}

static int value = 0;
}


public class SubClass extends SuperClass{


static{
System.out.println("SubClass init");
}

static final int value = 1;
}

public class Initlization {


public static void main(String[] args) {

System.out.println(SubClass.value);
//System.out.println(new SubClass());
//SuperClass[] x = new SuperClass[10];
}
}


解析:运行结果为1 .这里是被动引用。所获取的final修饰的变量已经在变量池中存在。


public class Test {

static Test t = new Test();

static int a ;
static int b = 0;

Test(){
a++;
b++;
}
    
public static  Test getNewTest(){
return t;
}


public static void main(String[] args) {
t.getNewTest();
System.out.println(a);
System.out.println(b);
}

运行结果:

1
0


解析:开始的时候会以为是11;但结合类加载和赋值的顺序就可发现。

  准备阶段:先加载等号左边的部分,并且赋予默认值。int的默认值为0;a和b执行++;得到的结果都是1.

   再进行初始化,因为a在定义时并没有赋值,而b在定义阶段已经赋值为0;所以结果为1,0



你可能感兴趣的:(JVM)