Java示例与ClassLoader


问题内容

我有小问题。我学习Java SE并找到ClassLoader类。我尝试在下面的代码中使用它:我试图使用URLClassLoader在运行时动态加载类。

URLClassLoader urlcl = new URLClassLoader(new URL[] {new URL("file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar")});
Class<?> classS = urlcl.loadClass("michal.collection.Stack");
for(Method field: classS.getMethods()) {
     System.out.println(field.getName());
}
Object object = classS.newInstance();
michal.collection.Stack new_name = (michal.collection.Stack) object;

Java虚拟机看不到我的类,并且出现以下异常:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: michal cannot be resolved to a type michal cannot be resolved to a type at Main.main(Main.java:62)

你知道我能解决这个问题吗?


问题答案:
Class<?> classS = urlcl.loadClass("michal.collection.Stack");
[...]
Object object = classS.newInstance();
michal.collection.Stack new_name = (michal.collection.Stack) object;

因此,您尝试动态加载类,然后静态引用它。如果您已经可以静态链接到它,则说明已加载并且无法再次加载。您需要通过反射访问方法。

您通常要做的是让加载的类从父类加载器实现一个接口。创建实例(通常只是一个实例)后,您可以通过带有接口类型的引用来引用它。

public interface Stack {
   [...]
}
[...]
    URLClassLoader urlcl = URLClassLoader.newInstance(new URL[] {
       new URL(
           "file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar"
       )
    });
    Class<?> clazz = urlcl.loadClass("michal.collection.StackImpl");
    Class<? extends Stack> stackClass = clazz.asSubclass(Stack.class);
    Constructor<? extends Stack> ctor = stackClass.getConstructor();
    Stack stack = ctor.newInstance();

(通常,堆栈溢出免责声明只涉及编译。)

您需要添加错误处理才能品尝。URLClassLoader.newInstance为增添了一些细化URLClassLoaderClass.newInstance已彻底破坏异常处理,应避免使用。