类加载器,打破双亲委派方法

类加载器

类加载器(Class Loader)是Java虚拟机(JVM)的一个子系统,负责将类的字节码加载到内存中,并生成对应的Java类对象。类加载器在Java程序运行时动态地加载需要的类文件,使得Java具备了动态加载类和实现动态链接的能力。
常见的类加载器有以下几种:

  1. 启动类加载器(Bootstrap Class Loader):
    ○ 是JVM的内置类加载器,负责加载Java的核心类库,如java.lang包中的类。由C++编写,不是Java类,是JVM的一部分。
  2. 扩展类加载器(Extension Class Loader):
    ○ 负责加载Java的扩展类库,位于JRE的lib/ext目录下的JAR文件中的类。它的父类加载器是启动类加载器。
  3. 应用程序类加载器(Application Class Loader):
    ○ 根据用户自定义的类路径加载类它的父类加载器是扩展类加载器。
  4. 自定义类加载器(Custom Class Loader):
    ○ 开发者可以通过继承java.lang.ClassLoader类实现自定义的类加载器。自定义类加载器可以根据特定需求来加载类,比如从网络或数据库中加载类。
    Java的类加载器采用了委托模型(Delegation Model),即类加载器在加载类时会首先委托给其父类加载器尝试加载,只有当父类加载器无法加载时,才由当前类加载器自己加载。这样的层级关系可以保证类的加载安全性,避免类的重复加载,同时也方便了类加载器的扩展和定制。

如何打破双亲委派模型

继承ClassLoader类,重写loadClass方法和findClass方法。

public class CustomClassLoader extends ClassLoader {
@Override
public Class loadClass(String name) throws ClassNotFoundException {
    // 尝试委托给父类加载器加载类
    Class loadedClass = super.loadClass(name);

    if (loadedClass == null) {
        // 如果父类加载器无法加载,尝试自己加载
        loadedClass = findClass(name);
    }

    return loadedClass;
}

@Override
protected Class findClass(String name) throws ClassNotFoundException {
    // 实现自己的类加载逻辑,例如从文件或网络中加载类的字节码
    byte[] classBytes = loadClassBytes(name);
    if (classBytes == null) {
        throw new ClassNotFoundException(name);
    }

    // 调用defineClass方法将字节码转换为类对象
    return defineClass(name, classBytes, 0, classBytes.length);
}

private byte[] loadClassBytes(String className) {
    // 实现加载类字节码的逻辑,例如从文件或网络中读取字节码数据
    // 返回一个包含类字节码的字节数组
    return null;
}

public static void main(String[] args) throws Exception {
    // 创建自定义类加载器实例
    CustomClassLoader customClassLoader = new CustomClassLoader();

    // 使用自定义类加载器加载类
    String className = "com.example.MyClass"; // 替换成你要加载的类名
    Class loadedClass = customClassLoader.loadClass(className);

    // 打印加载的类信息
    System.out.println("Loaded class: " + loadedClass.getName());
}

}

你可能感兴趣的:(jvm)