1.系統(tǒng)默認類加載器
BootStrap加載器:主要加載rt.jar,它是Java基礎(chǔ)類庫,里面有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);
}
}