自定义ClassLoader测试

参考博客:
深入分析ClassLoader

在阅读文章后,对例子进行更详细的解析。

  1. Parend接口
public interface Parent {
    public void say();
}
  1. Man实现类
public class Man implements Parent {
    @Override
    public void say() {
        System.out.println("hi, I'm a boy!");
    }
}
  1. MyClassLoader类
public class MyClassLoader extends ClassLoader {

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println("my class loader find class");
        byte[] bt = loadClassData(name);
        return defineClass(name, bt, 0, bt.length);
    }

    private byte[] loadClassData(String className) {
        InputStream is = getClass().getClassLoader().getResourceAsStream(className.replace(".", "/") + ".class");
        ByteArrayOutputStream byteSt = new ByteArrayOutputStream();
        int len = 0;
        try {
            while ((len = is.read()) != -1) {
                byteSt.write(len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return byteSt.toByteArray();
    }

}
  1. 测试类
public class Test {

    public static void main(String[] args) throws Exception {
        Test.test1();
        System.out.println("=========================");
        Test.test2();
    }

    private static void test1() throws Exception {
        MyClassLoader loader = new MyClassLoader();
        Class<?> c = loader.loadClass("testJvm.Man");
        System.out.println("Loaded by :" + c.getClassLoader());

        Parent p;
        System.out.println("Parent.class Loaded by :" + Parent.class.getClassLoader());
        Object parent = c.newInstance();
        System.out.println("c.newInstance() Loaded by :" + parent.getClass().getClassLoader());
        System.out.println("parent instanceof Parent :" + String.valueOf(parent instanceof Parent));
        p = (Parent) parent;
        System.out.println("p.getClass() Loaded by :" + p.getClass().getClassLoader());
        p.say();

        Man m;
        System.out.println("Man.class Loaded by :" + Man.class.getClassLoader());
        Object man = c.newInstance();
        System.out.println("c.newInstance() Loaded by :" + man.getClass().getClassLoader());
        System.out.println("man instanceof Man :" + String.valueOf(man instanceof Man));
        m = (Man) man;
        System.out.println("m.getClass() Loaded by :" + m.getClass().getClassLoader());
        m.say();
    }

    private static void test2() throws Exception {
        MyClassLoader loader = new MyClassLoader();
        Class<?> c = loader.findClass("testJvm.Man");
        System.out.println("Loaded by :" + c.getClassLoader());

        Parent p;
        System.out.println("Parent.class Loaded by :" + Parent.class.getClassLoader());
        Object parent = c.newInstance();
        System.out.println("c.newInstance() Loaded by :" + parent.getClass().getClassLoader());
        System.out.println("parent instanceof Parent :" + String.valueOf(parent instanceof Parent));
        p = (Parent) parent;
        System.out.println("p.getClass() Loaded by :" + p.getClass().getClassLoader());
        p.say();

        Man m;
        System.out.println("Man.class Loaded by :" + Man.class.getClassLoader());
        Object man = c.newInstance();
        System.out.println("c.newInstance() Loaded by :" + man.getClass().getClassLoader());
        System.out.println("man instanceof Man :" + String.valueOf(man instanceof Man));
        m = (Man) man;
        System.out.println("m.getClass() Loaded by :" + m.getClass().getClassLoader());
        m.say();
    }
}

结果:

Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
Parent.class Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
c.newInstance() Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
parent instanceof Parent :true
p.getClass() Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
hi, I'm a boy!
Man.class Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
c.newInstance() Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
man instanceof Man :true
m.getClass() Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
hi, I'm a boy!
=========================
my class loader find class
Loaded by :testJvm.MyClassLoader@5680a178
Parent.class Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
c.newInstance() Loaded by :testJvm.MyClassLoader@5680a178
parent instanceof Parent :true
p.getClass() Loaded by :testJvm.MyClassLoader@5680a178
hi, I'm a boy!
Man.class Loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
c.newInstance() Loaded by :testJvm.MyClassLoader@5680a178
man instanceof Man :false
Exception in thread "main" java.lang.ClassCastException: testJvm.Man cannot be cast to testJvm.Man
	at testJvm.Test.test2(Test.java:54)
	at testJvm.Test.main(Test.java:8)

自定义ClassLoader测试_第1张图片
第一个例子是自定义类加载器委托AppClassLoader对类进行加载,第二个例子是采用自定义类加载器本身对子类进行加载。
从第二个例子可以看出,虽然子加载器和父类加载器分别加载了Man这个类,但这两个类由于命名空间不同,所以不能相互转换。

你可能感兴趣的:(JVM)