Java

Java 知识量:11 - 45 - 220

11.3 类加载器><

ClassLoader类- 11.3.1 -

java.lang.ClassLoader是Java的类加载器类。类加载器是Java虚拟机的一部分,它负责将类字节码文件加载到虚拟机中,并将其转换为可以由虚拟机使用的类对象。

ClassLoader是一个抽象类,它定义了类加载器的基本行为和API。它有几个关键的方法,包括:

  • loadClass(String name): 加载指定名字的类。如果这个类还没有被加载,这个方法会调用父类加载器进行加载,如果父类加载器无法加载这个类,这个方法会尝试自己加载这个类。

  • findSystemClass(String name): 尝试在系统类路径(由系统属性java.class.path定义)中加载类。

  • findLoadedClass(String name): 查找已经加载的类。如果找到了,就返回这个类的ClassLoader;如果没有找到,就返回null。

  • defineClass(String name, byte[] b, int off, int len): 将一个byte数组转化为一个类,并返回这个类的ClassLoader。

  • resolveClass(Class<?> cls): 解析一个符号链接的类。

ClassLoader还有几种其他的方法,包括getSystemResources(String name)、getSystemClassLoader()、getParent()、definePackage(String name, String jarUrl, Certificate[] certs)等等。

以下是一个简单的ClassLoader应用示例:

import java.io.*;  
  
public class CustomClassLoader extends ClassLoader {  
    public CustomClassLoader(ClassLoader parent) {  
        super(parent);  
    }  
  
    public Class loadClassFromFile(String fileName) throws IOException {  
        File file = new File(fileName);  
  
        InputStream input = new FileInputStream(file);  
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();  
        int nextValue = input.read();  
        while (-1 != nextValue) {  
            byteStream.write(nextValue);  
            nextValue = input.read();  
        }  
  
        byte[] bytes = byteStream.toByteArray();  
        return defineClass(null, bytes, 0, bytes.length);  
    }  
}

在这个示例中,创建了一个CustomClassLoader类,它从父类加载器中继承,并包含一个从文件中加载类的方法。在loadClassFromFile方法中,首先创建一个File对象,然后通过FileInputStream读取文件的字节内容,再通过ByteArrayOutputStream将字节内容缓存起来。最后,使用defineClass方法将字节内容转化为类。

注意:这个示例假设已经有一个类的字节码文件。实际使用ClassLoader时,可能需要从网络或其他资源中获取类的字节码。此外,这个示例没有处理可能出现的异常,实际编程时需要添加适当的异常处理代码。

类加载程序层次结构- 11.3.2 -

Java提供了几种类型的类加载器,包括系统类加载器、扩展类加载器和应用程序类加载器,这些类加载器构成了类加载器的层次结构。这个层次结构允许Java平台在加载类时遵循特定的规则和策略,例如父优先策略(即子类加载器会首先尝试从父类加载器那里加载类)和只加载一次策略(即每个类只被加载一次)。

Java三类加载器具体如下:

  • 引导类加载器(Bootstrap Class Loader):负责加载Java的核心库(例如JAVA_HOME/jre/lib/rt.jar或sun.boot.class.path路径下的内容),该类加载器由C实现的原生代码来实现,并不继承自java.lang.ClassLoader。

  • 扩展类加载器(Extension Class Loader):负责加载Java的扩展库(例如JAVA_HOME/jre/lib/ext/*.jar或java.ext.dirs路径下的内容)。

  • 应用类加载器(Application Class Loader):加载应用程序类,此类加载器是扩展类加载器的子加载器,用于加载应用程序的类文件。