class loader

简介: 【8月更文挑战第4】

(class loader)机制来动态加载.class文件或JAR包中的类。类加载器是Java运行时环境的一部分,负责将.class文件转换为JVM可以理解和执行的java.lang.Class对象。

类加载器的主要类型:

  1. 启动类加载器(Bootstrap Class Loader)

    • 负责加载JDK的核心库,如java.lang.Object。
  2. 扩展类加载器(Extension Class Loader)

    • 负责加载JDK的扩展目录中的类库。
  3. 系统类加载器(System Class Loader)

    • 负责加载用户类路径(Classpath)上的类库。
  4. 自定义类加载器(User-defined Class Loader)

    • 开发者自定义的类加载器,用于实现特定的类加载需求。

类加载过程:

  1. 加载(Loading)

    • 读取.class文件的二进制数据,并创建一个java.lang.Class对象。
  2. 验证(Verification)

    • 确保加载的类信息符合JVM规范,没有安全问题。
  3. 准备(Preparation)

    • 分配静态变量的内存,并设置默认初始值。
  4. 解析(Resolution)

    • 将常量池中的符号引用转换为直接引用。
  5. 初始化(Initialization)

    • 执行类构造器<clinit>()方法,初始化静态变量。

如何使用类加载器:

  1. 使用系统类加载器

    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    Class<?> myClass = systemClassLoader.loadClass("com.example.MyClass");
    
  2. 使用URLClassLoader加载网络资源

    URL url = new URL("http://example.com/MyClass.class");
    URLClassLoader customClassLoader = new URLClassLoader(new URL[]{
         url});
    Class<?> myClass = customClassLoader.loadClass("com.example.MyClass");
    
  3. 自定义类加载器

    public class MyClassLoader extends ClassLoader {
         
        private String path;
    
        public MyClassLoader(String path) {
         
            this.path = path;
        }
    
        @Override
        public Class<?> findClass(String name) throws ClassNotFoundException {
         
            // 实现类的加载逻辑
            byte[] b = loadByteCode(name);
            return defineClass(name, b, 0, b.length);
        }
    
        private byte[] loadByteCode(String className) {
         
            // 从自定义路径加载.class文件
            // 这里只是一个示例,需要根据实际情况实现
            return null;
        }
    }
    
  4. 使用自定义类加载器加载类

    MyClassLoader myClassLoader = new MyClassLoader("/path/to/classes");
    try {
         
        Class<?> myClass = myClassLoader.loadClass("com.example.MyClass");
    } catch (ClassNotFoundException e) {
         
        e.printStackTrace();
    }
    

代码示例:

这是一个简单的自定义类加载器示例,用于从指定目录加载类:

import java.io.*;

public class DirectoryClassLoader extends ClassLoader {
   
    private String directoryPath;

    public DirectoryClassLoader(String directoryPath) {
   
        this.directoryPath = directoryPath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
   
        try {
   
            String path = directoryPath + File.separator + name.replace('.', File.separatorChar) + ".class";
            byte[] b = new byte[1024];
            FileInputStream fis = new FileInputStream(path);
            DataInputStream dis = new DataInputStream(fis);
            int i, count = 0;
            while ((i = dis.read()) != -1) {
   
                b[count++] = (byte) i;
            }
            dis.close();
            return defineClass(name, b, 0, count);
        } catch (IOException e) {
   
            throw new ClassNotFoundException(name);
        }
    }

    public static void main(String[] args) {
   
        try {
   
            DirectoryClassLoader dcl = new DirectoryClassLoader("/path/to/classes");
            Class<?> c = dcl.loadClass("com.example.MyClass");
            Object o = c.newInstance();
            System.out.println("Class loaded and instantiated successfully.");
        } catch (Exception e) {
   
            e.printStackTrace();
        }
    }
}
目录
相关文章
|
SQL 分布式计算 调度
Spark入门(一篇就够了)(三)
Spark入门(一篇就够了)(三)
854 0
|
资源调度 监控 数据处理
【Flink】Flink集群有哪些角色?各自有什么作用?
【4月更文挑战第18天】【Flink】Flink集群有哪些角色?各自有什么作用?
|
开发工具 git 开发者
|
消息中间件 存储 RocketMQ
Rocketmq如何保证消息不丢失
文章分析了RocketMQ如何通过生产者端的同步发送与重试机制、Broker端的持久化存储与消息重试投递策略、以及消费者端的手动提交ack与幂等性处理,来确保消息在整个传输和消费过程中的不丢失。
|
7月前
|
消息中间件 架构师 Java
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
|
11月前
|
存储 监控 算法
Flink 四大基石之 Checkpoint 使用详解
Flink 的 Checkpoint 机制通过定期插入 Barrier 将数据流切分并进行快照,确保故障时能从最近的 Checkpoint 恢复,保障数据一致性。Checkpoint 分为精确一次和至少一次两种语义,前者确保每个数据仅处理一次,后者允许重复处理但不会丢失数据。此外,Flink 提供多种重启策略,如固定延迟、失败率和无重启策略,以应对不同场景。SavePoint 是手动触发的 Checkpoint,用于作业升级和迁移。Checkpoint 执行流程包括 Barrier 注入、算子状态快照、Barrier 对齐和完成 Checkpoint。
2187 20
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
1912 25
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
消息中间件 负载均衡 算法
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
607 2
|
消息中间件 缓存 负载均衡
中间件的使用场景
【6月更文挑战第15天】
842 5