我正在编写一个将加载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);
}
}
人们如何在运行时加载不属于程序类路径的脚本,并且该类的二进制名称未知?
答案 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();
}