# 4.1 ClassLoader API

ClassLoader是一个抽象类,不能直接使用,因此我们需要继承并重写其中的方法。它的主要方法有defineClass、loadClass、findClass和resolveClass等及其重载方法。主要方法的定义如下:

 // 方法的输入是字节码的byte数组,输出是Class对象,它的作用是将字节码数组解析为Class对象
 protected final Class<?> defineClass(String name, byte[] b, int off, int len)
 
 // 通过类名称查找Class对象
 public Class<?> loadClass(String name)
 
 // 通过类名称查找类
 protected Class<?> findClass(String name)

 // 类加载后调用该方法完成类的链接
 protected final void resolveClass(Class<?> c)
1
2
3
4
5
6
7
8
9
10
11

先来实现一个简单的类加载器NetworkClassLoader,这个类加载器具备从网络加载类文件的能力, 实现代码如下。

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class NetworkClassLoader extends ClassLoader {
    
    // 下载地址
    private String downloadUrl;

    public NetworkClassLoader(String downloadUrl) {
        this.downloadUrl = downloadUrl;
    }

    // 实现类的查找方法
    @Override
    public Class findClass(String name) {
        byte[] b = loadClassData(name);
        return defineClass(name, b, 0, b.length);
    }
    
    // 从远程下载类文件,从而获得类的字节码数组
    private byte[] loadClassData(String name) {
        // load the class data from the connection
        // ... 
    }
    
    // 类名称转化为服务器下载的地址
    private String classNameToPath(String name) {
        return downloadUrl + "/" + name.replace(".", "/") + ".class";
    }

    // 测试方法
    public class Main {
        public static void main(String[] args) throws Exception {
            // 下载地址
            String baseUrl = "https://wwww.jrasp.com";
            // 初始化网络类加载器
            NetworkClassLoader loader = new NetworkClassLoader(baseUrl);
            // 加载位于 https://wwww.jrasp.com/Foo.class的类,并创建实例
            Object foo = loader.loadClass("Foo").newInstance();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

被加载的类Foo是一个简单类,在创建实例对象时输出"create new instance",Foo类的代码如下。

public class Foo {
    public Foo() {
        System.out.println("create new instance");
    }
}
// 运行Main方法,输出结果如下:
// create new instance
1
2
3
4
5
6
7

ClassLoader主要功能是类查找、加载和链接等过程, 除了加载类之外,类加载器还负责加载资源如配置文件或图片等。