Java 如何从文件夹中加载所有已编译的类?
我有一个文件夹操作符。在这个文件夹中我编译了文件(一个接口操作符和4个实现操作符的类)。目的是从这个文件夹加载所有的.class文件并在主程序中使用。我使用以下语句:Java 如何从文件夹中加载所有已编译的类?,java,reflection,Java,Reflection,我有一个文件夹操作符。在这个文件夹中我编译了文件(一个接口操作符和4个实现操作符的类)。目的是从这个文件夹加载所有的.class文件并在主程序中使用。我使用以下语句: File operatorFile = new File("D:\\operators"); URL operatorFilePath = operatorFile.toURL(); URL[] operatorFilePaths = new URL[]{operatorFilePath
File operatorFile = new File("D:\\operators");
URL operatorFilePath = operatorFile.toURL();
URL[] operatorFilePaths = new URL[]{operatorFilePath};
ClassLoader operatorsLoader = new URLClassLoader(operatorFilePaths);
//Plus,Minus,Multiply,Divide are classes that implement operator interface
Class[] operatorClass = new Class[]{ operatorsLoader.loadClass("Plus"), operatorsLoader.loadClass("Minus"),operatorsLoader.loadClass("Multiply") , operatorsLoader.loadClass("Divide") };
然后我使用此语句调用.class文件方法:
Method methodsInOperator;
Object instance;
String operatorSign;
for(Class operatorCls : operatorClass)
{
instance = operatorCls.newInstance();
methodsInOperator = operatorCls.getMethod("getSign", null);
operatorSign = (String)methodsInOperator.invoke(instance, null);
if(operatorSign.equals(elementInExpression[2]))
{
methodsInOperator = operatorCls.getMethod("calculate", new Class[] { double.class, double.class } );
output =(double)methodsInOperator.invoke(instance, firstNumber, secondNumber);
}
}
但下面的语句不会动态工作,如果我们将另一个.class文件放入operators文件夹,程序将停止工作
Class[] operatorClass = new Class[]{ operatorsLoader.loadClass("Plus"), operatorsLoader.loadClass("Minus"),operatorsLoader.loadClass("Multiply") , operatorsLoader.loadClass("Divide") };
我的目的是动态加载所有类,检查它们是否实现运算符,并根据getSing()方法选择最佳类。有人能帮我吗?这有两个部分:
public Class[] getOperators(File operatorFile) throws MalformedURLException, ClassNotFoundException {
ClassLoader operatorsLoader = new URLClassLoader(new URL[] { operatorFile.toURI().toURL() });
File[] files = operatorFile.listFiles(new FilenameFilter() {
@Override public boolean accept(File dir, String name) {
return name.endsWith(".class");
}
});
ArrayList<Class> operators = new ArrayList<>();
for (File file : files) {
String className = file.getName().substring(0, file.getName().length() - 6);
Class<?> clazz = operatorsLoader.loadClass(className);
if(OperatorInterface.class.isAssignableFrom(clazz)) {
operators.add(clazz);
}
}
return operators.toArray(new Class[operators.size()]);
}
public类[]getOperators(File Operator File)引发畸形的异常,ClassNotFoundException{
ClassLoader operatorsLoader=新的URLClassLoader(新的URL[]{operatorFile.toURI().toURL()});
File[]files=operatorFile.listFiles(新文件名过滤器(){
@重写公共布尔接受(文件目录,字符串名称){
返回名称.endsWith(“.class”);
}
});
ArrayList运算符=新的ArrayList();
用于(文件:文件){
字符串className=file.getName().substring(0,file.getName().length()-6);
Class clazz=operatorsLoader.loadClass(className);
if(运算符接口.class.isAssignableFrom(clazz)){
运算符。添加(clazz);
}
}
返回操作符.toArray(新类[operators.size()]);
}
如果一切顺利,则使用文件夹调用此方法应返回该文件夹中实现OpeartorInterface的所有类。我没有执行它-因此您可能必须修复代码中的一些问题。我建议使用SPI机制解决您的问题:
ServiceLoader<Operation> operations = ServiceLoader.load(Operation.class);
Iterator<Operation> ite = operations.iterator();
while (ite.hasNext()) {
Operation op = ite.next();
System.out.println("operation implementation is: " + op.getClass());
Number result = op.calc(3,4);
System.out.println("Result of 3 and 4 is " + result);
}
ServiceLoader operations=ServiceLoader.load(Operation.class);
迭代器ite=operations.Iterator();
while(ite.hasNext()){
操作op=ite.next();
System.out.println(“操作实现为:+op.getClass());
数字结果=运算计算(3,4);
System.out.println(“3和4的结果是”+结果);
}
如果您想添加更多操作,请添加类文件,并在operations/META-INF/services下的文件中添加一行具有完整限定名的新行。这是一款非常好的软件,可以让您完全按照自己的意愿进行操作:
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("my.project.prefix"))
.setScanners(new SubTypesScanner()),
.filterInputsBy(
new FilterBuilder().includePackage("my.project.prefix")));
其中my.project.prefix
指向您的文件夹
然后,您可以简单地使用reflections
实例来获取您的类:
Set<Class<? extends Operator>> operators =
reflections.getSubTypesOf(Operator.class);
set“程序停止工作”是什么意思。新类没有进入opeartorClass
数组?例如,我写了%class并将.class添加到文件夹中,我的程序应该仍然可以再次澄清,新的百分比应该出现在您的operatorClass
数组中?是的,我应该动态加载类。添加到文件夹中的每个.class文件也应该加载。您几乎肯定不需要加载所有类。就是你直接使用的那个。它所依赖的其他文件将自动加载。