Java:动态加载外部类

时间:2014-03-28 20:00:24

标签: java classpath classloader

我正在编写一个将加载Java脚本的应用程序。我目前有一个GUI,它使用JFileChooser来允许用户从他们的机器中选择一个脚本。脚本文件可以在任何地方。它不在类路径上。只有一个File对象来表示该脚本文件,我如何获得它的Class表示?

我知道要加载一个类,你需要它的二进制名,所以in.this.format。然而,问题是我不知道脚本编写者如何打包它。例如,他/她可能在开发时将脚本文件放在包foo.bar中。下载此脚本并将其放入我的文档后(即{b> not 在foo/bar中)后,我无法加载脚本而不知道它已打包在foo.bar中}。如果类名是Test并且我尝试通过执行URLClassLoader创建指向脚本文件的new URLClassLoader(new URL[] { new URL(scriptFile.toURI().toURL()) })而我执行classLoader.loadClass("Test")我会得到一个例外,说明该类名称错误,正确的名称为foo.bar.Test。但我怎么能提前知道呢?

这就是我现在所拥有的:

public class ScriptClassLoader extends URLClassLoader {

    private final File script;

    public ScriptClassLoader(File script) throws MalformedURLException {
        super(new URL[] { script.toURI().toURL() });
        this.script = script;
    }

    public Class<?> load() throws ClassNotFoundException {
        String fileName = script.getName();
        String className = fileName.substring(0, fileName.indexOf(".class"));
        return loadClass(className);
    }
}

人们如何在运行时加载不属于程序类路径的脚本,并且该类的二进制名称未知?

1 个答案:

答案 0 :(得分:1)

如果您只需要从给定的.class文件加载一个类,无论这个类如何命名,您都可以自己加载数据,然后调用ClassLoader的defineClass()方法:

RandomAccessFile raf = new RandomAccessFile(script, "r");
try {
    byte[] classData = new byte[(int) raf.length()];
    raf.readFully(classData);
    return super.defineClass(null, classData, 0, classData.length);
} finally {
    raf.close();
}