我有一类静态方法可以在类中保存的地图上执行,我希望在调用类时设置地图。我尝试过使用私有的构造函数,但它没有被调用。我的代码的相关部分是:
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
}
私有构造函数在这里是否正确使用,如果是这样,我做错了什么?
对不起,如果这是重复的话;我试过寻找答案,但我不确定该搜索什么!
答案 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的费用,直到(或除非)你需要。
警告:如果您的数据结构不是不可变的,即它们可以在初始化后更改,那么您可能不应该使用任何这些结构。