Java 使用URLClassLoader获得与默认类加载器相同的引用

Java 使用URLClassLoader获得与默认类加载器相同的引用,java,classloader,urlclassloader,Java,Classloader,Urlclassloader,我试图测试一个类是否可以多次加载到jvm,但使用不同的类加载器 因此,我的代码尝试加载一个类(类名“Tzvika”)两次 首先使用默认的类加载器 第二次尝试使用URLClassLoader 问题是我得到的URLClassLoader和默认类加载器的引用是相同的 我做错了什么 此处代码: public static void main(String[] args) { Tzvika t1 = new Tzvika(); System.out.println("t1 class lo

我试图测试一个类是否可以多次加载到jvm,但使用不同的类加载器 因此,我的代码尝试加载一个类(类名“Tzvika”)两次 首先使用默认的类加载器 第二次尝试使用URLClassLoader
问题是我得到的URLClassLoader和默认类加载器的引用是相同的 我做错了什么

此处代码:

public static void main(String[] args) {
    Tzvika t1 = new Tzvika();
    System.out.println("t1 class loader: " + t1.getClass().getClassLoader());

    Tzvika t2 = null;
    try {
        URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin/com/tzvika/sample/")});
        // same problem when i do this
        //URLClassLoader clsLoader = new URLClassLoader(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin/com/tzvika/sample/")});
        Class cls = clsLoader.loadClass("com.tzvika.sample.Tzvika");
        t2 = (Tzvika)cls.newInstance();
        System.out.println("t2 class loader: " + t2.getClass().getClassLoader());

    } catch (Exception e) {
        e.printStackTrace();
    }

}
这里是我的控制台输出:

t1 class loader: sun.misc.Launcher$AppClassLoader@1a52fdf
t2 class loader: sun.misc.Launcher$AppClassLoader@1a52fdf

创建不带父级的
URLClassLoader

URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin/com/tzvika/sample/")}, null);
还要注意,您应该指定类路径根的路径,即

URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin")});
为了更好地说明这一点,
URLClassLoader
的构造函数声明

将按照为类和类指定的顺序搜索URL 在指定的父类加载器中首次搜索后的资源

因此,当您尝试从这个
类加载器
加载一个类时,它将首先检查父类
类加载器
,它是引导类加载器,是否存在该类。因为父类加载器已经加载了
com.tzvika.sample.tzvika
类,所以它将返回它

现在,由于父类加载器和您的
clsLoader
加载的类不同,因此这些类的实例属于不同的类。因此,尽管您从两个
ClassLoader
s中都有
com.tzvika.sample.tzvika
,但它们有很大的不同


这就是different
ClassLoader
s的全部要点。

你的答案很有效,但我注意到了另外两个问题,我要说明你的答案。1.为什么要在父级中设置null?据我所知,只有引导的父类加载器是空的?2.为什么我在将对象从cls.newInstance()强制转换为com.tzvika.sample时得到ClassCastException。Tzvika@TzvikaVelich是的,我应该早点回答。我编辑了更多细节。如果还有什么不清楚的地方,请告诉我。