要在工厂中注册TrueFalseQuestion类,需要调用其静态初始化程序.要执行TrueFalseQuestion类的静态初始化程序,需要引用该类,或者需要在调用QuestionFactory.map.size()之前通过反射加载该类.如果要保持main方法不变,则必须引用它或通过QuestionFactory静态初始化程序中的反射加载它.我不认为这是一个好主意,但我只会回答你的问题:)如果你不介意QuestionFactory知道实现Question的所有类来构造它们,你可以直接引用它们或通过它们加载它们反射.就像是:
public class QuestionFactory {
static final HashMap map = new HashMap();
static {
this.getClassLoader().loadClass("TrueFalseQuestion");
this.getClassLoader().loadClass("AnotherTypeOfQuestion"); // etc.
}
public static void registerType(String questionName, String ques ) {
map.put(questionName, ques);
}
}
确保map的声明和构造在静态块之前.如果您不希望QuestionFactory对Question的实现有任何了解,则必须将它们列在由QuestionFactory加载的配置文件中.我能想到的唯一其他(可能是疯狂的)方法是查看实现Question :)的类的整个类路径.如果所有实现Question的类都需要属于同一个包,那么这可能会更好 – 注意:我不赞同这个解决方案;)
我不认为在QuestionFactory静态初始化程序中执行任何操作的原因是因为像TrueFalseQuestion这样的类有自己的静态初始化程序,它们调用QuestionFactory,在那时它是一个不完整构造的对象,这只是一个问题.有一个配置文件只是列出你想让QuestionFactory知道如何构造的类,然后在它的构造函数中注册它们是一个很好的解决方案,但它意味着改变你的主方法.