Salmon的全栈知识 Salmon的全栈知识
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
npm

(进入注册为作者充电)

  • JVM基础

    • 初识JVM
    • 字节码文件详解
    • 运行时数据区
    • 垃圾回收
  • JVM实战

    • 内存调优
    • GC调优
    • 性能调优
  • JVM高级

    • GraalVM
    • 新一代的GC
    • 揭秘Java工具
  • JVM原理

    • 栈上的数据存储
    • 对象在堆上是如何存储的?
    • 方法调用的原理
    • 异常捕获的原理
    • JIT即时编译器
    • 垃圾回收器原理
  • JVM面试

    • 什么是JVM?
    • 了解过字节码文件的组成吗?
    • 说一下运行时数据区
    • 哪些区域会出现内存溢出,会有什么现象?
    • JVM在JDK6-8之间在内存区域上有什么不同
    • 类的生命周期
    • 什么是类加载器?
      • 启动类加载器
      • 扩展类加载器
      • 应用程序类加载器
      • 自定义类加载器
      • 总结:
    • 什么是双亲委派机制
    • 如何打破双亲委派机制
    • Tomcat的自定义类加载器
    • 如何判断堆上的对象没有被引用??
    • JVM 中都有哪些引用类型?
    • ThreadLocal中为什么要使用弱引用?
    • 有哪些常见的垃圾回收算法?
    • 有哪些常用的垃圾回收器?
    • 如何解决内存泄漏问题?
    • 常见的JVM参数?
  • 《JVM》笔记
  • JVM面试
Salmon
2024-03-12
目录

什么是类加载器?

  • 关联课程内容

    • 基础篇-类加载器的分类
    • 基础篇-启动类加载器
    • 基础篇-扩展和引用程序类加载器
    • 基础篇-JDK9之后的类加载器
  • 回答路径

    • 类加载器的作用
    • 启动类加载器
    • 扩展/平台类加载器
    • 应用程序类加载器
    • 自定义类加载器(加分项)

类加载器负载在类的加载过程中将字节码信息以流的方式获取并加载到内存中。JDK8及之前如下:

img

JDK9之后均由Java实现:

img

# 启动类加载器

启动类加载器(Bootstrap ClassLoader)是由Hotspot虚拟机提供的类加载器,JDK9之前使用C++编写的、JDK9之后使用Java编写。

默认加载Java安装目录/jre/lib下的类文件,比如rt.jar,tools.jar,resources.jar等。

img

//String类 核心类 由启动类加载器加载,在Java中无法获得启动类加载器
System.out.println(java.lang.String.class.getClassLoader());

打印结果为:

img

在Java代码中无法获得启动类加载器。

# 扩展类加载器

扩展类加载器(Extension Class Loader)是JDK中提供的、使用Java编写的类加载器。JDK9之后由于采用了模块化,改名为Platform平台类加载器。

默认加载Java安装目录/jre/lib/ext下的类文件。

img

//nashorn包中的类,使用java script引擎打印Hello World 由扩展类加载器加载
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello World!');");
System.out.println(ScriptEngineManager.class.getClassLoader());

打印结果(JDK17平台类加载器):

img

# 应用程序类加载器

应用程序类加载器(Application Class Loader)是JDK中提供的、使用Java编写的类加载器。默认加载为应用程序classpath下的类。

# 自定义类加载器

自定义类加载器允许用户自行实现类加载的逻辑,可以从网络、数据库等来源加载类信息。自定义类加载器需要继承自ClassLoader抽象类,重写findClass方法。

img

package q4classloader;

import org.apache.commons.io.FileUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;

//自定义类加载器
public class MyClassLoader extends ClassLoader{

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        String filename = name.substring(name.lastIndexOf(".") + 1);

        byte[] bytes = new byte[0];
        try {
            bytes = FileUtils.readFileToByteArray(new File("D:\\jvm\\data\\" + filename + ".class"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取字节码信息的二进制数据,调用defineClass方法
        return defineClass(name, bytes, 0, bytes.length);
    }

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

        MyClassLoader myClassLoader = new MyClassLoader();

        Class<?> clazz = myClassLoader.loadClass("com.itheima.springbootclassfile.pojo.vo.UserVO");

        //打印字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }

    }
}

# 总结:

1.启动类加载器(Bootstrap ClassLoader)加载核心类

2.扩展类加载器(Extension ClassLoader)加载扩展类

3.应用程序类加载器(Application ClassLoader)加载应用classpath中的类

4.自定义类加载器,重写findClass方法。

JDK9及之后扩展类加载器(Extension ClassLoader)变成了平台类加载器(Platform ClassLoader)

上次更新: 2025/03/09, 18:29:07
类的生命周期
什么是双亲委派机制

← 类的生命周期 什么是双亲委派机制→

Theme by Vdoing | Copyright © 2022-2025 Salmon's Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式