Java类的加载过程学习笔记

Java类的加载过程

JVM将类加载过程分为三步:装载、链接、初始化,其中链接分为三步:验证、准备、解析。

类的加载过程

  • 装载load:查找并加载类的二进制数据;

  • 链接link:

    1. 验证verify:确保被加载类的正确性;
    2. 准备preparation:为类的静态变量分配内存,并将其初始化为默认值;
    3. 解析resolution:把类的符号引用转换为直接引用
  • 初始化initiation:为类的静态变量赋予正确的初始值;

类的初始化

6种情况可以导致类的初始化:

public class LoadMethod {

    static {
        System.out.println("LoadMethod is Load");
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

        // 1.第一次实例化类
        ClassA classA = new ClassA();

        // 5.反射
        Class<ClassA> classAClass = (Class<ClassA>) Class.forName("com.stupidzhe.jdklearning.classloader.ClassA");

        // 3.调用类中的静态变量
        System.out.println(ClassA.name);

        // 4.调用类中的静态方法
        ClassA.print();

        // 5.初始一个类的子类
        ClassB classB = new ClassB();

        // 6.该类被作为启动类
    }
}

类的初始化步骤

1)如果这个类还没有被加载和链接,那就先进行加载和链接;

2)假如该类存在直接父类,并且父类没被初始化,那就初始化直接的父类(ps. 在一个类加载器中,类只能加载一次);

3)如果类中存在初始化语句,那就执行这些初始化语句。

类的装载

类的加载指的是将类的.class文件中二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的Class对象,用来封装类在方法区类的对象。

Class对象封装了类在方法区的数据结构(比如静态变量、常量),并且给程序员提供了访问方法区内的数据结构的接口;加载类的方式有以下几种:

  1. 从本地系统直接加载
  2. 通过网络下载.class文件
  3. 从归档文件中加载.class文件
  4. 将Java源文件动态编译为.class文件
  5. 从专有数据库中提取.class文件

加载器

JVM的类加载是通过ClassLoader及其子类来完成的。

  1. Bootstrap ClassLoader:负责加载$JAVA_HOME中jre/lib/rt.jar,是由cpp实现的;
  2. Extension ClassLoader:负责加载Java平台扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/ext/*.jar或-Djava.ext.dirs指定目录下的jar包;
  3. App ClassLoader:负责加载classpath中指定的jar包及目录中class;
  4. Custom ClassLoader:属于用户自定义的ClassLoader,根据j2ee规范自行实现。

JVM通过双亲委派模式模式进行类加载

为什么要用双亲委派模式?

好处是Java类随着它的加载器一起具备了一种带优先级的层次关系,通过这样层次关系可以避免类的重复加载

ps.还有个上下文类加载器不符合双亲委派模式

猜你喜欢

转载自my.oschina.net/StupidZhe/blog/1785595