1.系统默认类加载器
BootStrap加载器:主要加载rt.jar,它是Java基础类库,里面有String等类(String.class.getClassLoader() = null)
Extension加载器:主要加载jre/lib/ext目录下jar,其中包含Java的一些加密方法等
Application(System)加载器:加载classpath下jar
2.类加载器三种机制
委托:当加载一个Class时,当前加载器会先委托父加载器加载 如果父加载器没能加载 则自己加载
可见:父加载器加载的Class,对子加载器都是可见的,而子类加载的Class父加载器不知道
单一:一个Class只能被加载一次
3.看看一下的例子
3.1
@Test
public void testBootstrapClassLoader() {
ClassLoader classLoader = String.class.getClassLoader();
try {
Class<?> loadClass = classLoader.loadClass("com.boomsecret.domain.Person");
Object obj = loadClass.newInstance();
Method method = loadClass.getMethod("setUsername", String.class);
method.invoke(obj, "Bootstrap ClassLoader");
Method getUsernameMethod = loadClass.getMethod("getUsername");
Object invoke = getUsernameMethod.invoke(obj);
System.out.println(invoke);
System.out.println(obj);
} catch (Exception e) {
System.out.println(e);
}
}
空指针异常:BootStrap加载器获取不到,classLoader为null 我们可以看下源码3.2
@Test
public void testExtensionClassLoader() {
ClassLoader classLoader = AccessBridge.class.getClassLoader();
try {
Class<?> loadClass = classLoader.loadClass("com.boomsecret.domain.Person");
Object obj = loadClass.newInstance();
Method method = loadClass.getMethod("setUsername", String.class);
method.invoke(obj, "Extension ClassLoader");
Method getUsernameMethod = loadClass.getMethod("getUsername");
Object invoke = getUsernameMethod.invoke(obj);
System.out.println(invoke);
System.out.println(obj);
} catch (Exception e) {
System.out.println(e);
}
}
ClassNotFoundException:(AccessBridge是jre/lib/ext中类)所以取到的是Extension加载器,自然是找不到com.boomsecret.domain.Person的
3.3
@Test
public void testApplicationClassLoader() {
ClassLoader classLoader = getClass().getClassLoader();
try {
Class<?> loadClass = classLoader.loadClass("com.boomsecret.domain.Person");
Object obj = loadClass.newInstance();
Method method = loadClass.getMethod("setUsername", String.class);
method.invoke(obj, "Application ClassLoader");
Method getUsernameMethod = loadClass.getMethod("getUsername");
Object invoke = getUsernameMethod.invoke(obj);
System.out.println(invoke);
System.out.println(obj);
} catch (Exception e) {
System.out.println(e);
}
}
正常:Application加载器加载classpath中类
3.4 显示加载Class Api1
@Test
public void testLoadClass() {
try {
Class<?> loadClass = Class.forName("com.boomsecret.domain.Person");
Object obj = loadClass.newInstance();
Method method = loadClass.getMethod("setUsername", String.class);
method.invoke(obj, "Application ClassLoader");
Method getUsernameMethod = loadClass.getMethod("getUsername");
Object invoke = getUsernameMethod.invoke(obj);
System.out.println(invoke);
System.out.println(obj);
} catch (Exception e) {
System.out.println(e);
}
}
3.5 显示加载Class APi2
@Test
public void testLoadClass2() {
try {
Class<?> loadClass = Class.forName("com.boomsecret.domain.Person",
true, getClass().getClassLoader());
Object obj = loadClass.newInstance();
Method method = loadClass.getMethod("setUsername", String.class);
method.invoke(obj, "Application ClassLoader");
Method getUsernameMethod = loadClass.getMethod("getUsername");
Object invoke = getUsernameMethod.invoke(obj);
System.out.println(invoke);
System.out.println(obj);
} catch (Exception e) {
System.out.println(e);
}
}