我正在使用一个抽象类和该类的一组(不断增长的)子类。由于某些原因,A 的所有子类都应该实现单例模式。在应用程序启动期间存在一个List>
并且我想初始化所有单例实例。
据我所知,我的选择是采用反射,按照准则强制所有 A 实现类都必须具有已定义的构造函数,并通过 o.getDeclaredConstructor().newInstance(); 调用该构造函数。 。
我还尝试了一种不同的方法,使用静态方法的重载。也就是说,A 定义了一个静态初始化方法,并且所有子类都必须重新实现该方法。可以通过反射再次调用该调用。
第一种方法有一个明显的缺点,即违反编程指南只会导致运行时错误,而不会导致编译时错误。第二个更糟糕的是,如果子类没有实现静态方法,则仅调用 A
中的方法,而不会抛出明显的异常。
那么:如何在一组单例类中强制采用统一的方式进行初始化?
编辑:
配置类在启动期间生成 A
的所有子级的列表,这些类可以以编程方式直接在配置类中注册,也可以通过配置文件进行配置:
private void initModules() {
Configurator.addModule("modulename", SubOfA.class);
...
}
private void initModuleFile() {
...
String name = in.readLine();
String classname = ...;
String modulename = ...;
Configurator.addModule(modulename, Class.forName(classname));
}
I'm working with an abstract class and a (growing) set of subclasses of this class. For certain reasons all subclasses of A should implement the singleton pattern. During startup of the application there exists a List<Class<? extends A>>
and I would like to initialize all singleton-instances.
From what I see, my option here is to go for Reflection, enforcing by guidelines that all A-implementing classes have to have a defined constructor and invoke that via o.getDeclaredConstructor().newInstance();
.
I've also tried a different approach where I used overloading of static methods. That is, A defined a static initialize
method and all subclasses had to reimplement that method. The call can again be invoked via reflection.
The first approaches has the obvious disadvantage that violations of the programming-guideline result only in runtime-errors, not in compile-time errors. The second is even worse, if a subclass does not implement the static method, only the method in A
is called with no apparent exception thrown.
So: How do I enforce a uniform way to initialize in a set of singleton classes?
Edit:
A configuration-class generates a list of all children of A
during startup, those classes can be either registered directly in the configuration class programmatically or configured via a configurationfile:
private void initModules() {
Configurator.addModule("modulename", SubOfA.class);
...
}
private void initModuleFile() {
...
String name = in.readLine();
String classname = ...;
String modulename = ...;
Configurator.addModule(modulename, Class.forName(classname));
}
发布评论
评论(1)
在这种情况下,常见的方法就像您的第一个建议:
Class.forName("...").newInstance()
(这可以,当然,可以通过某种工厂模式进行封装。)
由于在 Java 中,您无法强制子类实现特定的构造函数,因此唯一可行的方法是通过设计指南/契约要求默认构造函数。
作为示例,看一下 Android 的 Parcelable:
In this case the common approach is like your first proposal:
Class.forName("...").newInstance()
(This can, of course, be encapsulated by some kind of factory pattern.)
Since, in Java, you cannot enforce a particular constructor to be implemented by subclasses, the only viable way is to demand a default constructor by design guidelines/contracts.
As an example, have a look at Android's Parcelable: