我有一个由执行文件处理的类实现的接口,比如搜索或其他。
public interface FileProcessorInterface {
public void processFile(String fileName);
}
然后我对每种文件类型都有不同的实现:
public class TxtProcessor implements FileProcessorInterface {
@Override public void processFile(String fileName) { //do the work }
}
因此,我有处理器的 Utilizer,它有一个允许注册每个类的方法,如下所示:
class Utilizer {
Map <String, Class> registered = new HashMap<>();
public void registerClass(String fileExt, Class clazz) {
registered.put(fileExt, clazz);
}
public void processFile(String fileName) {
//1) get the registered class from registered map (omitted because easy and not relevant)
//2) create an instance of the class using reflection (omitted because easy and not relevant)
FileProcessorInterface p = ....
p.processFile(fileName);
}
到目前为止一切正常。
现在,我提供了我的接口的许多实现。
而且我很想为每个实现类提供一个静态初始化程序,该初始化程序在 Utilizer 中注册自身,在我之前的 TxtProcessor 的情况下,它将是:
class TxtProcessor implements FileProcessorInterface {
//previous code
static {
Utilizer.registerClass("txt", TxtProcessor.class);
}
}
问题是这个静态方法永远不会被调用,因为在应用程序的“静态可达”代码中没有对我的 TxtProcessor 类的引用,因为它是通过反射实例化的。所以jvm不调用静态初始化器。
假设我有两个部分:作为 Utilizer 的“通用代码”,另一方面是实现;它必须被认为是动态提供的东西,因此 Utilizer 部分不知道它。
事实上,这个想法正是每个类都会注册自己,而不会触及 Utilizer。
我很难想出一个不将某种形式的实现“知识”放在 Utilizer 端(并且保持简单)的解决方案,只是因为未调用静态初始化程序的问题。如何克服这一点?