初识类加载器

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 我们可以看下源码
初识类加载器_第1张图片
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);
    }
}

你可能感兴趣的:(初识类加载器)