我正在开发一个命令行应用程序,它在运行时加载用户指定的文本翻译器(通过命令行 arg 提供的类文件/jar 的路径)。基本上我接受了这个论点并使用它来创建一个 URLClassLoader。然后我需要找到实现 Transable 接口(interface)的 URLClassloader 可用的所有类。
现在我只允许这个命令行参数是一个包含类文件的目录。使解决方案相当简单(下面的代码)。但老实说,我不喜欢这个解决方案,因为它分解了 jar 文件、jar 文件的目录等......此外,这显然分解了任何具有定义包的类,因为 loadClass 需要包含包的全名。谁有更好的方法?
File d = new File(path);
if(d.isDirectory()) {
URL url = d.toURI().toURL();
ClassLoader cl = new URLClassLoader(new URL[]{url});
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".class");
}
};
for(File f : d.listFiles(filter)) {
String name = f.getName().substring(0, f.getName().indexOf("."));
String key = "";
if(name.endsWith("Translator")) {
key = name.substring(0, name.indexOf("Translator"));
}
else if(name.endsWith("translator")) {
key = name.substring(0, name.indexOf("translator"));
}
else
key = name;
Class c = cl.loadClass(name);
if(Transable.class.isAssignableFrom(c)) {
Transable t = (Transable)c.newInstance();
env.registerTranslator(key, t);
}
else {
System.out.println("[ClassLoader] "+c.getCanonicalName()+" will not be loaded. It is not a translator class");
}
}
}
else {
throw new Error("NOT IMPLEMENTED");
}
最佳答案
如果你继续沿着这条路走下去,你可能只需要蛮力。据我所知,默认的类加载器甚至不会将类加载到 JVM 中,除非它以某种方式被引用。这意味着,您的一些类基本上是不可见的,除非您知道它们的完全限定类名来加载它们。
您可能需要重新考虑您的要求。因为加载一组已为其指定类名的转换器会容易得多。
关于Java,获取实现特定接口(interface)的 URLClassLoader 可用的所有类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5023696/