构造函数中的一类静态方法

时间:2012-01-12 17:39:12

标签: java constructor hashmap static-constructor

我有一类静态方法可以在类中保存的地图上执行,我希望在调用类时设置地图。我尝试过使用私有的构造函数,但它没有被调用。我的代码的相关部分是:

public class MyClass
{
    private static final String KEYS = "ABC";
    private static final String[] DATA = {"AAA", "BBB", "CCC"};
    private static HashMap<Character, String> myMap;

    private MyClass() {
        System.out.println("Running constructor");
        populateMyMap();
    }

    private static void populateMyMap() {
        myMap = new HashMap<Character, String>();
        for (int i=0; i < KEYS.length; i++) {
            myMap.put(KEYS.charAt(i), DATA[i]);
        }
    }

    //various static methods
}

私有构造函数在这里是否正确使用,如果是这样,我做错了什么?

对不起,如果这是重复的话;我试过寻找答案,但我不确定该搜索什么!

4 个答案:

答案 0 :(得分:8)

不,私有构造函数不是你想要的。构造函数初始化类的实例(当您调用new MyClass()时),但静态不属于实例,因此不应从构造函数初始化。首次加载类时要进行的初始化应该位于类级别的static块中。

static {
   populateMyMap();
}

但是你永远不应该使用静态(全局)状态。静态使您的系统难以测试,它比实例状态更细微(例如,每个类的负载都有一个副本)并且通常更难使线程安全。

请考虑让您的地图成为您班级的实例成员

答案 1 :(得分:5)

在其他几个答案中已经提到了静态初始化程序块。但实际上我在野外更频繁地发现以下习语:

public class MyClass
{
    private static HashMap<Character, String> myMap = createMyMap();

    private static HashMap<Character, String> createMyMap() {
        HashMap<Character, String> myTmpMap = new HashMap<Character, String>();
        for (int i=0; i < KEYS.length; i++) {
            myTmpMap.put(KEYS.charAt(i), DATA[i]);
        }
        return myTmpMap;
    }
}

答案 2 :(得分:3)

使用静态初始化程序:

public class MyClass
{
    static {
    //init
    }
}

答案 3 :(得分:0)

实现这一目标有两种方法。一种是使“populateMyMap”方法成为静态初始化器(或A.H.建议的方法)。然后保证在第一次静态调用之前执行。这通常是最好的方法,假设运行populateMyMap的成本足够小而不被注意,或者几乎每次运行应用程序时都要使用该类的功能。

如果运行“populateMyMap”需要花费大量时间并且要么您可能不使用该功能执行应用程序,或者您希望推迟执行populateMyMap,那么您可以使用替代方法直到需要数据,以免不必要地增加启动时间。

如果第二种方法是您想要的,那么您应该切换结构并使用Singleton而不是静态方法。使方法(和数据)非静态,并让它们的每个用户在调用方法之前获取Singleton实例。在(私有)构造函数中调用“populateMyMap”。是的,我知道,单身人士声誉不好,人们总是说“避免他们,因为他们只是伪装的全球方法”,但静态方法也只是全球性的方法。你什么都没有失去。这样你就不需要支付执行populateMyMap的费用,直到(或除非)你需要。

警告:如果您的数据结构不是不可变的,即它们可以在初始化后更改,那么您可能不应该使用任何这些结构。