java - 如何从文件夹加载所有编译的类?

标签 java reflection

我有一个文件夹 operators 。在这个文件夹中我编译了文件(一个接口(interface)操作符和 4 个实现操作符的类)。目的是从这个文件夹加载所有 .class 文件并在主程序中使用。我使用这个语句:

    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() 方法选择最佳类。有人能帮我吗?

最佳答案

这有两个部分:

  1. 首先列出给定文件夹中的文件。
  2. 然后加载具有给定接口(interface)/类型的类。

我写了一个小方法来执行此操作 - 您可以将您的逻辑建立在该方法的基础上。

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()]);
}

如果一切顺利,使用文件夹调用此方法应该会返回该文件夹中实现 OpeartorInterface 的所有类。我没有执行它 - 因此您可能需要修复代码的一些问题。

关于java - 如何从文件夹加载所有编译的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32222151/

相关文章:

java - 将非静态变量更改为静态变量

泛型的 Java 反射

java - 如何检查方法是否在 Java 中返回 Collection<Foo>?

c# - 使用字符串值创建新实例

java - 多对多关系 Hibernate

java - 我可以附加到不同进程中的 JVM 吗?

java - 如何将数据库AWS secret 传递到tomcat context.xml中?

c# - 在 C# 中使用反射设置属性 {get;}

java - 在 Java 中反射 map

java - 用变量实例化