我有几个类(class),如下所示
public class TrueFalseQuestion implements Question{
static{
QuestionFactory.registerType("TrueFalse", "Question");
}
public TrueFalseQuestion(){}
}
...
public class QuestionFactory {
static final HashMap<String, String > map = new HashMap<String,String>();
public static void registerType(String questionName, String ques ) {
map.put(questionName, ques);
}
}
public class FactoryTester {
public static void main(String[] args) {
System.out.println(QuestionFactory.map.size());
// This prints 0. I want it to print 1
}
}
如何更改
TrueFalseQuestion
类,以便始终运行静态方法,以便在运行main方法时得到1而不是0?我不想对主要方法进行任何更改。我实际上是在尝试实现子类向工厂注册的工厂模式,但是我简化了此问题的代码。
最佳答案
要向工厂注册TrueFalseQuestion
类,需要调用其静态初始化程序。要执行TrueFalseQuestion
类的静态初始化器,需要在调用QuestionFactory.map.size()
之前引用该类或通过反射将其加载。如果要保持不变main
方法,则必须引用它或通过反射将其加载到QuestionFactory
静态初始值设定项中。我不认为这是个好主意,但我只回答您的问题:)如果您不介意QuestionFactory
知道所有实现Question
来构造它们的类,则可以直接引用它们或通过加载它们反射。就像是:
public class QuestionFactory {
static final HashMap<String, String > map = new HashMap<String,String>();
static {
this.getClassLoader().loadClass("TrueFalseQuestion");
this.getClassLoader().loadClass("AnotherTypeOfQuestion"); // etc.
}
public static void registerType(String questionName, String ques ) {
map.put(questionName, ques);
}
}
确保
map
的声明和构造在static
块之前。如果您不希望QuestionFactory
对Question
的实现有任何了解,则必须在QuestionFactory
加载的配置文件中列出它们。我认为可以做的另一种(可能是疯狂的)方法是在整个类路径中查找实现Question
的类:)如果所有实现Question
的类都需要属于同一个包,那可能会更好—注意:我不支持此解决方案;)我不认为在
QuestionFactory
静态初始值设定项中执行任何此操作的原因是,像TrueFalseQuestion
这样的类具有自己的静态初始值设定项,这些初始值设定项会调用QuestionFactory
,这当时是一个未完全构造的对象,仅是在问麻烦。一个配置文件仅列出您希望QuestionFactory
知道如何构造的类,然后在其构造函数中注册它们是一个很好的解决方案,但这将意味着更改main
方法。