欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java语法基础 类加载

程序员文章站 2022-06-19 15:43:36
类加载过程虚拟机只加载程序执行时所需要的的类文件。JVM不是一开始就把所有的类都加载进内存中,而是只有第一次遇到某个需要运行的类时才会加载,且只加载一次。类加载的过程主要分为三个部分:加载Java 将字节码数据从不同的数据源读取到 JVM 中,并映射为 JVM 认可的数据结构(Class 对象),这里的数据源可能是各种各样的形态,比如 jar 文件,class 文件,甚至是网络数据源等链接类定义信息转入 JVM 运行的过程中初始化执行类初始化的代码逻辑,使用双亲委派机...

类加载过程

虚拟机只加载程序执行时所需要的的类文件。

JVM不是一开始就把所有的类都加载进内存中,而是只有第一次遇到某个需要运行的类时才会加载,且只加载一次

类加载的过程主要分为三个部分:

  1. 加载

    Java 将字节码数据从不同的数据源读取到 JVM 中,并映射为 JVM 认可的数据结构(Class 对象),这里的数据源可能是各种各样的形态,比如 jar 文件,class 文件,甚至是网络数据源等

  2. 链接

    类定义信息转入 JVM 运行的过程中

  3. 初始化

    执行类初始化的代码逻辑,使用双亲委派机制避免重复加载 Java 类型。

而链接又可以细分为三个小部分:

  1. 验证

    JVM 需要核验字节信息是符合 Java 虚拟机规范

  2. 准备

    创建类或者接口中的静态变量,并初始化静态变量的初始值。分配所需要的内存空间,不会去执行更进一步的 JVM 指令。

  3. 解析

    ​ 常量池中的符号引用替换为直接引用。类,接口,方法和字段等各方面的解析。

    Java语法基础 类加载

最后是初始化。

类加载器

引导类加载器 (启动类加载器)(根类加载器)(bootstrap class loader)(没有对应ClassLoader对象,c++编写)(没有父子关系)

平台类加载器(扩展类加载器)(ExtClassLoader)

系统类加载器(应用类加载器)(AppClassLoader)

JVM的类加载机制主要有如下3种。

  1. 全盘负责:所谓全盘负责,就是当一个类加载器负责加载某个Class时,该Class所依赖和引用其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入。

  2. 双亲委派:父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父加载器,依次递归,如果父加载器可以完成类加载任务,就成功返回;只有父加载器无法完成此加载任务时,才自己去加载。

  3. 缓存机制。缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区中搜寻该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓冲区中。这就是为很么修改了Class后,必须重新启动JVM,程序所做的修改才会生效的原因。

    除了引导类加载器以外,每一个类加载器都有一个父类加载器。

自定义类加载器(通常是为了加密)

继承ClassLoader类,重写findClass方法

父类的loadClass()方法将类加载委托给父类加载器,当该类未加载且父类加载器无法加载时,才会调用findClass()方法。

public class MyClassLoader extends ClassLoader{
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //return super.findClass(name);
        // 实现该方法必须要做到以下几点
        /****
        	* 1.来自本地文件系统或其他来源的类加载及字节码。
        	* 2.调用ClassLoader父类的defineClass()方法,向jvm提供字节码。
        	*/
    }
}

本文地址:https://blog.csdn.net/by2233/article/details/111028104