Java: 自实例化类

我正在为大学项目开发一个匹配工具,这个工具主要由多个简单的匹配算法组成。现在我想让人们能够轻松地添加他们自己的算法,并且只需将.java文件添加到项目文件夹中,就能自动将这些算法包含到集合中。

每个算法必须实现MatchingComponentInterface接口,我希望实现这个接口的每个类都能通知集合它的存在,这样集合就能动态地组装自己,包括那个算法。

为了简化起见,让我们假设主程序和集合代码如下所示:

class Main {  @Getter  private Ensemble ensemble = new Ensemble();  public static void main(String[] args){    //SomeMatchingComponent.touch();    Result res = ensemble.match(args[0], args[1]);  }}

请注意被注释掉的touch()调用,我稍后会回到这个话题。

public class Ensemble{  private List<MatchingComponentInterface> components;  private Result combinedResult = new Result();  public void addComponent(MatchingComponentInterface component){    components.add(component);  }  public void match(Object first, Object second){    components.forEach(component -> {      combinedResult.addResult(component.match(first, second));    });  }}

此外,我可能有几个MatchingComponent实现,看起来大致如下:

public class SomeMatchingComponent implements MatchingComponentInterface{  //这只会在代码中第一次提及类时执行  //然而我想在不提及类的情况下执行它  static {    MatchingComponent foo = new MatchingComponent();    Main.getEnsemble().addComponent(foo);  }  //static void touch(){}  public Result match(Object first, Object second){    //匹配魔法  }}

现在看看静态代码块。只要我在代码的其他地方使用这个类,这个代码就会执行。然而在这个例子中,这不会发生,因为我也注释掉了touch()方法以及主方法中的调用。

当集合被构建时,主方法需要预先知道所有组件,以便触及并将它们添加到集合中。然而我想在没有任何这些操作的情况下添加它们。它们应该自动添加自己。

我的问题是:有没有一种方法可以强制执行静态代码块,而不需要硬编码哪些组件存在,或者让接口调用自己所有实现的方法呢?


回答:

实际上,我已经找到了一个编程解决方案。使用reflections库,可以检测任何类或接口的所有子类或实现,因此通过一些这样的代码,我可以实现我需要的功能:

public void addAllComponents(Ensemble ensemble){  //"matching.component"是一个前缀,因为所有组件都在一个以此命名的包中  Reflections reflections = new Reflections("matching.component");  Set<Class<? extends MatchingComponentInterface>> classes     = reflections.getSubTypesOf(MatchingComponentInterface.class);    classes.forEach(aClass -> {    try{      ensemble.addComponent(aClass.getConstructor().newInstance());    }     catch (NoSuchMethodException | IllegalAccessException |           InstantiationException | InvocationTargetException e) {      //适当处理异常    }  });}

我是在这里的一个非常旧的问题中找到这个库的:

如何在Java中以编程方式获取接口的所有实现列表?

Related Posts

如何对SVC进行超参数调优?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

如何在初始训练后向模型添加训练数据?

我想在我的scikit-learn模型已经训练完成后再…

使用Google Cloud Function并行运行带有不同用户参数的相同训练作业

我正在寻找一种方法来并行运行带有不同用户参数的相同训练…

加载Keras模型,TypeError: ‘module’ object is not callable

我已经在StackOverflow上搜索并阅读了文档,…

在计算KNN填补方法中特定列中NaN值的”距离平均值”时

当我从头开始实现KNN填补方法来处理缺失数据时,我遇到…

使用巨大的S3 CSV文件或直接从预处理的关系型或NoSQL数据库获取数据的机器学习训练/测试工作

已关闭。此问题需要更多细节或更清晰的说明。目前不接受回…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注