ran*_*ght 8 java static-members static-initializer
我有几个课程,如下所示
public class TrueFalseQuestion implements Question{
static{
QuestionFactory.registerType("TrueFalse", "Question");
}
public TrueFalseQuestion(){}
}
Run Code Online (Sandbox Code Playgroud)
...
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
}
}
Run Code Online (Sandbox Code Playgroud)
如何更改TrueFalseQuestion类以便始终运行静态方法,以便在运行main方法时得到1而不是0?我不希望主方法有任何改变.
我实际上是在尝试实现子类向工厂注册的工厂模式,但我已经简化了这个问题的代码.
你可以打电话:
Class.forName("yourpackage.TrueFalseQuestion");
Run Code Online (Sandbox Code Playgroud)
这将加载类而不实际触摸它,并将执行静态初始化程序块.
要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);
}
}
Run Code Online (Sandbox Code Playgroud)
确保map声明和构造在static块之前.如果您不想QuestionFactory了解其实现Question,则必须将它们列在加载的配置文件中QuestionFactory.我能想到的唯一其他(可能是疯狂的)方法是查看实现的类的整个类路径Question:)如果所有实现的类Question都需要属于同一个包,那可能会更好- 注意:我不赞同这个解决方案;)
我不认为在QuestionFactory静态初始化程序中执行任何操作的原因是因为类TrueFalseQuestion具有自己的静态初始化程序QuestionFactory,这些接收程序在此时是一个未完全构造的对象,这只是在寻找麻烦.有一个配置文件只是列出你想QuestionFactory知道如何构建的类,然后在它的构造函数中注册它们是一个很好的解决方案,但它将意味着改变你的main方法.
| 归档时间: |
|
| 查看次数: |
8730 次 |
| 最近记录: |