如何使用URLClassLoader加载* .class文件?

我和Reflection一起玩,我想我会做一些加载类并打印类中所有字段的名字。 我已经做了一个小小的Hello World世界types的东西来检查:

kent@rat:~/eclipsews/SmallExample/bin$ ls IndependentClass.class kent@rat:~/eclipsews/SmallExample/bin$ java IndependentClass Hello! Goodbye! kent@rat:~/eclipsews/SmallExample/bin$ pwd /home/kent/eclipsews/SmallExample/bin kent@rat:~/eclipsews/SmallExample/bin$ 

基于上述,我得出两个结论:

  • 它存在于/home/kent/eclipsews/SmallExample/bin/IndependentClass.class
  • 有用! (所以它必须是一个可以通过类加载器加载的正确的.class文件)

然后是使用reflection的代码:(引起exception的线被标记)

 import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; public class InspectClass { @SuppressWarnings("unchecked") public static void main(String[] args) throws ClassNotFoundException, MalformedURLException { URL classUrl; classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/IndependentClass.class"); URL[] classUrls = { classUrl }; URLClassLoader ucl = new URLClassLoader(classUrls); Class c = ucl.loadClass("IndependentClass"); // LINE 14 for(Field f: c.getDeclaredFields()) { System.out.println("Field name" + f.getName()); } } } 

但是当我运行它时,我得到:

 Exception in thread "main" java.lang.ClassNotFoundException: IndependentClass at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at InspectClass.main(InspectClass.java:14) 

我的问题:

  1. 我在上面做错了什么? 我该如何解决?
  2. 有没有办法加载几个类文件并迭代它们?

URLClassLoader(URL[])构造函数的Javadocs :

使用默认委派父级ClassLoader为指定的URL构造一个新的URLClassLoader。 在首先在父类加载器中进行search之后,将按照为类和资源指定的顺序来searchURL。 任何以“/”结尾的URL都被认为是指向一个目录。 否则,假定该URL是指将根据需要下载和打开的JAR文件。

所以你有两个select:

  1. 参考.class文件所在的目录
  2. 将.class文件放入一个JAR中并引用它

(1)在这种情况下更容易,但是(2)如果您正在使用networking资源,可以很方便。

您必须将包含.class文件的目录或jar文件提供给URLClassLoader:

 classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/"); 

是的,你可以根据你的喜好加载许多类

您必须通过给类名称的完全限定类名称与其包path一起加载类,

 Class c = ucl.loadClass("com.mypackage.IndependentClass"); 

我遇到了类似的问题,但是我的类文件驻留在名为“customElements”的包中。 在这种情况下,需要将URL构build到根文件夹上方的文件夹中,并在加载方法中传递包括该包的类的完整名称。 例如,就我而言, url如下所示:

 File customElementsDir = new File("D:/My Space"); //File customElementsDir = new File("D:\\customElements"); URL[] urls = null; try { URL url = customElementsDir.toURI().toURL(); urls = new URL[] { url }; } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

而实际的加载是这样的:

 clazz = childFirstClassLoader .loadClass("customElements.CustomLoadableClass"); 

其中childFirstClassLoader是我的类加载器。