2

代码如下

它的作用是将所有类加载到我放置在主目录中的 jar 文件中。

import java.io.File;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.net.URLClassLoader;
import java.net.URL;
import java.util.Enumeration;
import java.lang.ClassLoader;
public class Plugin extends ClassLoader {
public static void main(String[] args) throws Exception {

    File file = new File(System.getProperty("user.home") + "/HelloWorld.jar");

    URLClassLoader clazzLoader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()});

    JarFile jarFile = new JarFile(file);
    Enumeration<JarEntry> entries = jarFile.entries();

    while (entries.hasMoreElements()) {
        JarEntry element = entries.nextElement();
        if (element.getName().endsWith(".class")) {
            try {
                Class c = clazzLoader.loadClass(element.getName().replaceAll(".class", "").replaceAll("/", "."));
                c.newInstance(); // this proves that class is loaded
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    Class cls = Class.forName("HelloWorld");
    cls.newInstance();
    Plugin p = new Plugin();
    p.checkIfLoaded();

}

public void checkIfLoaded() {
System.out.println("coming in");
if (findLoadedClass("HelloWorld") != null){
        System.out.println("Yepee, HelloWorld class is loaded !");
}
}

}

我的 HelloWorld 就像在https://github.com/HarishAtGitHub/doc/blob/master/makeExecutableJar/HelloWorld.java

jar 是使用上面提到的我的 github 帐户中的说明获得的。

c.newInstance()作品。

我是怎么确认的?

静态块被执行了......

Class.forName("HelloWorld")抛出ClassNotFoundException

findLoadedClass("HelloWorld") 为空..

我不明白为什么会出现这种奇怪的行为?

请指导...

4

2 回答 2

3

这是一个类加载器问题。

根据Javadocs toClass.forName,您正在使用当前类的类加载器查找该类。作为您的主类,这将是 JVM 的引导类加载器(并且或多或少只包括标准库以及您作为-cp命令行参数提供的任何内容)。它不会委托给您作为局部变量实例化的类加载器,因此不会返回该类加载器可以找到的类。

如果您要明确指定类加载器,然后调用

Class.forName("HelloWorld", true, clazzloader)

然后将搜索您刚刚创建的类加载器,并且应该找到您的类。

于 2014-02-13T09:23:32.653 回答
1

因为 Class.forName(String) 使用 currentClassLoader 并且您已将类加载到不同的 ClassLoader 中。

根据javadoc,调用 Class.forName(String) 相当于:

Class.forName(className, true, currentLoader) 
于 2014-02-13T09:23:32.180 回答