阅读 86

Java类加载过程

一、Java如何运行

  • Java代码文件会编译成可运行的.class字节码文件;
  • JVM在运行.class文件时需要依赖的.class文件或者jar包里面的某个.class,则通过类加载器去加载到内存;
  • JVM会基于自己的字节码引擎,来执行加载到内存里已写好的类

二、类加载到使用的过程

加载->验证->准备->解析->初始化->使用->卸载

  1. 加载:JVM会将需要代码运行时需要的类加载到内存中(通过类加载器);
  2. 验证:根据Java虚拟机规范,校验加载的.class文件内容是否符合指定的规范(例如字节码文件被篡改);
  3. 准备:主要是分配内存空间;

如果有public static int count;类似这样的变量 【类变量】,分配内存空间的同时初始化一个默认值

  1. 解析:实际上是将符号引用替换成直接引用
  2. 核心阶段初始化: 在准备阶段,对于count这个静态变量会默认初始化0,但是赋值操作是在初始化阶段,如下的Configuration.getInt("studnet.count");赋值操作;另外,静态代码块的执行也是在这个阶段。
public class LoadStudent {
    public static int count = Configuration.getInt("studnet.count");
    
    public static Map<String, Student> students;
    
    static {
        initStudents();
    }
    
    public static void initStudents() {
        this.students = new HashMap<String, Student>();
    }
}

复制代码

类初始化的时机:当类被使用的到的时候,如:LoadStudent load = new LoadStudent(); 如果初始化一个类的时候,发现该类有父类,必须先初始化他的父类

实现上述初始化类的过程,需要由类加载器来完成,Java中的类加载器有:

(1)启动类加载器Bootstrap ClassLoader,启动JVM,会加载jdk目录下的lib目录下的核心类库

(2)拓展类加载器Extension ClassLoader,启动JVM,会加载jdk目录下的lib/ext目录下的拓展类库

(3)应用程序类加载器Application ClassLoader,加载classpath环境变量哦指定的路径中的类,可以理解成加载你写到的Java代码到内存

(4)自定义类加载器,除了上述几种类加载器之外,还可以自定义类加载器

他们亲子层结构关系如下图:

双亲委派机制:简单来说,子类加载器先会找父类加载器去加载类,找不到的话再由子类去加载

关注下面的标签,发现更多相似文章
评论