一个类加载器是一个对象负责加载类数据,类ClassLoader是一个抽象对象,指定一个二进制类名称,类加载器将会去定位或者生成类定义数据,一个典型的做法是将类名转为文件名,然后读取类文件。
每个类对象都包含一个ClassLoader的引用,该类加载器,加载了本类
数组类对象不能通过类加载器创建,但是java运行时将会自动创建,数组的类加载器和内部的元素是一样的,如果数组的元素类型是基本类型,则没有类加载器
应用实现了ClassLoader(可以扩展jvm动态加载类的方式)
安全管理器将会使用类加载做安全相关的管理工作
类加载器使用委托模型搜索类和资源,每一个子类类加载器都有一个父类类加载器指针,当子类类加载器被请求加载一个资源的时候,
子类加载器将首先委托父类类加载器,如果父类加载器查找不到,才由子类类加载器加载资源,jvm内置加载器“bootstrap class loader”,没有父类类加载器,其他类加载器都是它的子类。
类加载器可以并行加载资源,叫做可并行类加载器,必须在初始化的时候,调用“ ClassLoader.registerAsParallelCapable”方法注册本身,注意,ClassLoader默认具备并行能力,但是子类类加载器需要手动注册,才有并行加载能力。
在某些环境下,委托模型不是严格的继承,类加载器需要有并行加载能力,否则类加载有可能导致死锁,因为加载锁在加载过程中一直持有。
正常情况下,jvm加载类从本地文件系统中读取文件,依赖每个平台,比如在unix系统,jvm加载类文件根据环境变量ClASSPATH的值
然而,有些类不是本地文件的形式,比如他们存储在网络中,他们可以被应用程序动态生成,defineClass方法可以讲二进制数组转换为一个类对象,实例可以通过Class.newInstance方法创建。
通过类加载器加载的类,他们的对象的方法或者构造器可能引用其他类,类加载器也会调用loadClass方法,去加载他们。
举个例子,一个应用可以创建一个网络类加载器,从一个服务器上下载类文件,比如:
ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();
. . .
网络类加载器必须定义一个findClass和loadClassData方法,可以通过网络加载一个类定义数据,一旦加载完成
可以通过defineClass方法创建一个类实例,比如:
class NetworkClassLoader extends ClassLoader {
String host;
int port;
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
. . .
}
}
类二进制名称
合法的二进制类名称:
- “java.lang.String”
- “javax.swing.JSpinner$DefaultEditor”
- “java.security.KeyStore$Builder$FileBuilder$1”
- “java.net.URLClassLoader$3$1”
如果需要完整的资料可以去这里“传送门”



