2012-01-12 82 views
4

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

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 
} 

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

对不起,如果这是重复的;我试过寻找答案,但我不知道要搜索什么!

回答

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; 
    } 
} 
+0

是的,如果是简单地初始化一个值,这是更好的选择。 – 2012-01-12 18:03:05

3

使用静态初始化:

public class MyClass 
{ 
    static { 
    //init 
    } 
} 
8

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

static { 
    populateMyMap(); 
} 

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

考虑对你的地图的实例成员类的代替。

+0

这也需要重写所有的静态方法作为实例方法 - 在我看来这是一件好事。 – emory 2012-01-12 18:11:50

0

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

另一种方法是如果运行“populateMyMap”需要花费大量时间,或者您可能不会使用某些应用程序执行的功能,或者您希望推迟执行填充我的地图,直到需要数据,以免不必要地增加启动时间。

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

警告:如果你的数据结构都不是一成不变的,即它们可以将其初始化后改变,那么你可能不应该使用这些结构。