概述
所有Class都是由ClassLoader加载到内存中,负责通过各种方式将Class信息的二进制数据流读入JVM内部,转换为一个与目标类对应的Class对象实例。然后交给JVM进行链接和初始化等操作
类的加载分类:显示加载和隐式加载
显示:Class.forName()或者this.getClass().getClassLoader().loadClass()
隐式:通过虚拟机自动加载到内存
package chapter204;
public class UserTest {
public static void main(String[] args) throws ClassNotFoundException {
User user = new User();//隐式加载
Class<?> aClass = Class.forName("chapter204.User");//显示加载
}
}
类的加载器唯一的情况下加载的类唯一。
类的加载器分类
引导类加载器(BootStrap ClassLoader):C/C++ 核心类库,jvm自身需要的类(java、javax、sun),不继承ClassLoader,加载扩展类加载器和系统类加载器
扩展类加载器(Extension ClassLoader):继承于ClassLoader,父类是BootStrap ClassLoader
系统类加载器(Application ClassLoader):使用频率最高
自定义类加载器:
测试不同类的加载器
package chapter204;
public class ClassLoaderTest1 {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader);
ClassLoader bootClassLoader = extClassLoader.getParent();
System.out.println(bootClassLoader);
Class<?> clazz = Class.forName("java.lang.String");
ClassLoader classLoader = clazz.getClassLoader();
System.out.println(classLoader);
// 自定义类默认使用系统类加载器
ClassLoader classLoader1 = Class.forName("chapter204.ClassLoaderTest1").getClassLoader();
System.out.println(classLoader1);
// 数组类型加载:使用的类加载器与数组元素的类的加载器相同
String[] strArr = new String[10];
System.out.println(strArr.getClass().getClassLoader());//null 使用的是引导类加载器
ClassLoaderTest1[] classLoaderTest1s = new ClassLoaderTest1[10];
System.out.println(classLoaderTest1s.getClass().getClassLoader());//
int[] intArr = new int[10];
System.out.println(intArr.getClass().getClassLoader());//null
}
}
ClassLoader源码解析
ClassLoader与现有类加载器的关系
主要方法:
@CallerSensitive
public final ClassLoader getParent() {
if (parent == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Check access to the parent class loader
// If the caller's class loader is same as this class loader,
// permission check is performed.
checkClassLoaderPermission(parent, Reflection.getCallerClass());
}
return parent;
}
loadClass方法剖析:
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
protected Class<?> loadClass(String name, boolean resolve)
//resolve:true 加载Class的同时要解析
throws ClassNotFoundException
{
//同步操作 保证只能加载一次。
synchronized (