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

时间:2009-04-10 18:10:33

标签: java reflection

我正在玩Reflection,我想我会创建一个加载类的东西并打印出类中所有字段的名称。 我已经制作了一个小型的世界类型的课程来检查:

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的代码:(标记导致异常的行)

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. 有没有办法加载多个类文件并迭代它们?

5 个答案:

答案 0 :(得分:38)

来自Javadocs for the URLClassLoader(URL[]) constructor

  

使用默认委托父ClassLoader为指定的URL构造一个新的URLClassLoader。首次在父类加载器中搜索后,将按照为类和资源指定的顺序搜索URL。 任何以“/”结尾的网址都假定为引用目录。否则,假定URL引用JAR文件,该文件将根据需要下载和打开。

所以你有两个选择:

  1. 请参阅.class文件所在的目录
  2. 将.class文件放入JAR并引用
  3. 在这种情况下,

    (1)更容易,但如果你使用网络资源,(2)可以很方便。

答案 1 :(得分:10)

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

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

是的,你可以加载任意数量的课程

答案 2 :(得分:6)

您必须通过提供类名称的完全限定类名来加载类,其包路径为,

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

答案 3 :(得分:0)

我遇到了类似的问题,但我的类文件位于名为“customElements”的包中。在这种情况下,需要构建URL直到根文件夹正上方的文件夹,并且在load方法中,应该传递包括包的类的完整名称。例如,就我而言;网址如下:

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是我的类加载器。

答案 4 :(得分:0)

我遇到了同样的问题,但是我找到了解决办法:

              const tempLists = [];

              // eslint-disable-next-line no-restricted-syntax
              for (const list of response.data.lists) {
                tempLists.push({ ...list, items: [] });
              }

这为您提供了jar和class路径。从这里您可以管理您的流程。