Java ClassLoader的简单介绍
本文是阅读《深入理解Java虚拟机》第七章类加载器相关部分过程中生成的阅读笔记。简单介绍了ClassLoader的是什么,主要的类型和双亲委派模型。
ClassLoader是什么
虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。
–《深入理解Java虚拟机》(周志明)
ClassLoader就是这里提到的类加载器。类加载器的作用就是根据类的全限定名获取类的二进制字节流。这个动作在Java虚拟机的外部实现。
类与类加载器的关系
类加载器除了加载类的作用外,还和被加载的类本身共同确保类的唯一性。对于两个相同的Class文件,当使用不同的类加载器加载时他们就i是不同的。
例如当使用了不同ClassLoader加载同一个类时,会导致instanceof的结果为false。
package com.suifeng.loader;
import java.io.IOException;
import java.io.InputStream;
public class ClassLoaderTest {
public static void main(String[] args) throws Exception{
ClassLoader myClassLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
try {
String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
InputStream is = getClass().getResourceAsStream(fileName);
if (is == null) {
return super.loadClass(name);
}
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b.length);
} catch (IOException e) {
e.printStackTrace();
throw new ClassNotFoundException(name);
}
}
};
Class<?> aClass = myClassLoader.loadClass("com.suifeng.loader.TestClass");
Object obj = aClass.newInstance();
System.out.println(obj.getClass());
System.out.println(obj instanceof com.suifeng.loader.TestClass);
}
}
输出结果为
class com.suifeng.loader.TestClass
false
可以看到这里的obj是TestClass的对象,但使用instanceof关键字判断时仍然返回false。这是因为使用了不同类加载器jvm将他们识别为两个不同的类。obj是自定义类加载的,而另一个是由系统应用程序类加载器加载的。
类加载器类型
Java提供了三种类加载器。分别是启动类加载器
,扩展类加载器
,应用程序类加载器
。