类加载过程

虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制

1 类的生命周期:

加载、验证、准备、解析、初始化、使用、卸载。
其中 验证、准备、解析部分统称为连接

2 类的加载过程

2.1 加载
在加载阶段,Java虚拟机对类完成以下三个步骤:
1)通过一个类的全限定名来获取定义此类的二进制字节流
2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
3)在内存中生成一个代表这个类的Java.lang.Class对象,作为方法区这个类的各种数据的访问入口
2.2 验证
确保class文件中包含的字节流符合虚拟机要求,并且不会影响虚拟机自身安全。验证阶段大致完成四个检验动作:文件格式、元数据、字节码及符号引用验证
2.3 准备
在方法区中为类变量分配内存并设置类变量的初始值.进行内存分配的只包含类变量,不包含实例变量,实例变量将在对象初始化时随着对象一起分配在Java堆中
2.4 解析
将常量池中的符号引用替换为直接引用
2.5初始化
执行静态语句块,变量赋值

3 类加载器

负责实现类的加载动作,同时两个类的比较只有在同一个类加载器加载的情况下才有意义,若类加载器不同 ,两个类必然不相等
类型:
启动类加载器(Bootstrap ClassLoader) 无法被Java程序直接引用,无父类加载器
扩展类加载器(Extension ClassLoader)继承启动类加载器 开发者可直接使用
应用程序类加载器(Application ClassLoader)继承扩展类加载器 负责加载用户类路径指定的类库

4 双亲委派模型
类加载器.png

如图所示,这种类加载器之间层次关系便被成为双亲委派模型,除了启动类加载器外,其余加载器皆有自己的父类加载器
工作过程
加载一个类时首先自己不会去尝试加载这个类,而是逐步向上让父类加载器加载,只有父类加载器无法完成类加载时,子加载器才会尝试自己加载
优点
安全,防止用户自己篡改了核心类库
避免了类的重复加载
代码实现

    protected Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
            // 检查class类是否已加载
            Class c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // 抛出ClassNotFoundException 异常
                    // 父类加载器无法加载
                }

                if (c == null) {
                    // 父类加载器无法加载
                    // 调用本身的findClass方法来加载
                    c = findClass(name);
                }
            }
            return c;
    }```


你可能感兴趣的:(类加载过程)