【问题标题】:How to use URLClassLoader to load a *.class file?如何使用 URLClassLoader 加载 *.class 文件?
【发布时间】:2009-04-10 18:10:32
【问题描述】:

我正在玩反射,我想我会做一些东西来加载一个类并打印类中所有字段的名称。 我制作了一个小型的 hello world 类来检查一些东西:

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 文件)

然后是使用反射的代码:(标记导致异常的行)

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

【问题讨论】:

  • 你在禁止什么警告?
  • 一个常见的错误是使用当前目录作为 URL,但也将当前目录用于普通类。因为默认父级是系统类加载器,所以您的类加载器没有机会加载该类。
  • file:///home/kent/eclipsews/SmallExample/bins/IndependentClass.class 应该是:file:///home/kent/eclipsews/SmallExample/bin/IndependentClass.class ?
  • Tom hawtin:是的,Class 是一个原始类型。这是我想要的,因为我将继续在它的基础上构建并希望能够加载任何类。所以我压制了那个警告。我会记住这个常见的错误,我相信我很快就会做到。 :-) 大卫:是的,这是一个错字。我现在更正了。
  • 两个答案都是正确的。我对信息最多的那个给出了我接受的答案。我宁愿两个都接受。嗯..

标签: java reflection


【解决方案1】:

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

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

所以你有两个选择:

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

(1) 在这种情况下更容易,但如果您使用网络资源,(2) 会很方便。

【讨论】:

    【解决方案2】:

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

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

    是的,您可以加载任意数量的类

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        我遇到了类似的问题,但我的类文件位于名为“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 是我的类加载器。

        【讨论】:

          【解决方案5】:

          我遇到了同样的问题,但我发现这是一个解决方案:

          System.getProperty("java.class.path")
          

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

          【讨论】:

            猜你喜欢
            • 2015-12-22
            • 1970-01-01
            • 2019-02-08
            • 2014-09-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-07
            • 1970-01-01
            相关资源
            最近更新 更多