Java:自实例化类



我正在为一个大学项目构建一个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{
//this is only executed the first time the class is mentioned in the code
//however I want this do be executed without mentioning the class
static {
MatchingComponent foo = new MatchingComponent();
Main.getEnsemble().addComponent(foo);
}
//static void touch(){}
public Result match(Object first, Object second){
//matching magic
}
}

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

在构建集成时,main方法需要事先知道所有组件,以便触摸并将它们添加到集成中。但是我想把它们加起来,而不需要这些。

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

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

public void addAllComponents(Ensemble ensemble){
//"matching.component" is a prefix as all components are in a package with that name
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) {
//Handle exceptions appropriately
}
});
}

我在一个非常古老的问题中发现了这个库:

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

最新更新