您的位置:首页 > 编程语言 > Java开发

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

2017-10-21 19:59 621 查看

一、类的生命周期

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

    b)  各个阶段

    


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

  

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

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

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

        

       2)连接

验证:确保Class文件中的字节流所包含的信息是安全的。
准备:正式为类变量分配内存并设置类变量初始值。
解析:虚拟机将常量池中的符号引用改为直接引用。
 


             
   

       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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息