获取静态初始化块以在Java中运行而不加载类 [英] get static initialization block to run in a java without loading the class

查看:125
本文介绍了获取静态初始化块以在Java中运行而不加载类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个班级,如下所示

I have a few classes as shown here

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类,以便始终运行静态方法,以便在运行主方法时得到1而不是0?我不想对主要方法进行任何更改.

How can I change TrueFalseQuestion class so that the static method is always run so that I get 1 instead of 0 when I run my main method? I do not want any change in the main method.

我实际上正在尝试实现子类向工厂注册的工厂模式,但是我简化了此问题的代码.

I am actually trying to implement the factory patterns where the subclasses register with the factory but i have simplified the code for this question.

推荐答案

要将TrueFalseQuestion类注册到工厂,需要调用其静态初始化程序.要执行TrueFalseQuestion类的静态初始化器,需要引用该类,或者需要在调用QuestionFactory.map.size()之前通过反射将其加载.如果要保持main方法不变,则必须引用它或通过反射将其加载到QuestionFactory静态初始值设定项中.我认为这不是一个好主意,但是我只回答您的问题:)如果您不介意QuestionFactory知道所有实现Question来构造它们的类,则可以直接引用它们或通过反射加载它们.像这样:

To register the TrueFalseQuestion class with the factory, its static initializer needs to be called. To execute the static initializer of the TrueFalseQuestion class, the class needs to either be referenced or it needs to be loaded by reflection before QuestionFactory.map.size() is called. If you want to leave the main method untouched, you have to reference it or load it by reflection in the QuestionFactory static initializer. I don't think this is a good idea, but I'll just answer your question :) If you don't mind the QuestionFactory knowing about all classes that implement Question to construct them, you can just reference them directly or load them through reflection. Something like:

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块之前.如果您不希望QuestionFactoryQuestion的实现有任何了解,则必须在QuestionFactory加载的配置文件中列出它们.我认为可以做的另一种(可能是疯狂的)方法是,在整个类路径中查找实现Question的类:)如果要求所有实现了Question的类都属于该类,那可能会更好相同的程序包-注意:我不认可该解决方案;)

Make sure map's declaration and construction is before the static block. If you don't want QuestionFactory to have any knowledge of the implementations of Question, you'll have to list them in a configuration file that gets loaded by QuestionFactory. The only other (possibly insane) way I could think to do it, would be to look through the entire classpath for classes that implement Question :) That might work better if all classes that implemented Question were required to belong to the same package -- NOTE: I am not endorsing this solution ;)

我不认为在QuestionFactory静态初始值设定项中进行任何此操作的原因是因为像TrueFalseQuestion这样的类具有自己的静态初始值设定项,该静态初始值设定项会调用QuestionFactory,这在当时是一个不完全构造的对象,这只是自找麻烦.拥有一个配置文件仅列出您希望QuestionFactory知道如何构造的类,然后将其注册到其构造函数中是一个很好的解决方案,但这将意味着更改您的main方法.

The reason I don't think doing any of this in the QuestionFactory static initializer is because classes like TrueFalseQuestion have their own static initializer that calls into QuestionFactory, which at that point is an incompletely constructed object, which is just asking for trouble. Having a configuration file that simply lists the classes that you want QuestionFactory to know how to construct, then registering them in its constructor is a fine solution, but it would mean changing your main method.

这篇关于获取静态初始化块以在Java中运行而不加载类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆