第七章 虚拟机类加载机制

2017-04-25  本文已影响0人  一颗北上广的心

类加载机制:
虚拟机把描述类的数据从Class文件加载到内存,并队数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。

类生存过程:类加载-使用-卸载
类加载过程 : 加载-连接-初始化
连接过程: 验证-准备-解析

过程说明

  1. 通过一个类的全限定名来获取定义此类的二进制字节流.
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构.
  3. 在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据访问入口.

为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全.
文件格式验证,元数据验证,字节码验证,符号引用验证.

正式为类变量分配内存并设置类变量(static 修饰的) 初始值,这些变量所使用的内存都将在方法区中进行分配.

class Test{
    int x ; // 对象实例化的时候会分配
    static int y =123; //准备后为0, 初始化后为123
    static final int z = 123;//准备后为123
}

5种触发初始化的情况:

  • new对象,read/write static field(except final static field), invoke static method,如果发现这个类没有被加载过;

类中static初始化:
static字段和static语句块按照先后顺序被<clinit>()收集并执行。父类的优先于子类执行。

public class SubCls extends Parent {

    static String sub_y = "sub static field y";

    static {
        System.out.println("sub static block");
        sub_x = "sub static block x";
        sub_y = "sub static block y";
        // System.out.println(sub_x); can not use the field after the block
    }

    static String sub_x = "sub static field x";

    public static void main(String[] args) {
        System.out.println(sub_x); // static field x
        System.out.println(sub_y); // y - static block
    }
}
class Parent {

    static String p_x = "parent static field x";

    static {
        System.out.println("parent static block");
        p_x = "parent static block x";
    }
}
parent static block
sub static block
sub static field x
sub static block y

双亲委派模型

工作过程:

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。每一个层次的类加载器都是如此。只有当父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。

好处:

Java类随着他的类加载器一起具备了一种带有优先级的层次关系。相反如果没有使用双亲委派模型,由各个类加载器自行去加载的话,如果用户编写了一个称为java.lang.Object的类,并防在ClassPath中,那系统中将出现多个不同的Object类。

类加载器:

上一篇 下一篇

猜你喜欢

热点阅读