在Java中强制初始化枚举类型

时间:2010-09-29 00:40:00

标签: java enums enumeration

我试图找到一种方法来强制Java加载/初始化枚举类型(嵌套在包含静态Map的类中)。

这对我很重要,因为枚举类型具有填充所述映射的构造函数,并且没有明确的方法来初始化此枚举,映射将保持为空。我试图使用Class.forName,但这似乎不起作用。

我想我可以创建一个枚举实例(并将其存储在其他集合或其他东西中),但我想知道是否有一种优雅的方法来实现这一点。

4 个答案:

答案 0 :(得分:10)

引用类时会加载一个类。这适用于所有类。

您遇到的问题更可能是在任何静态块之前初始化Enum值。即你不能引用构造函数中静态块中的初始化。 (通常在构造函数中初始化静态内容是一个坏主意)您需要在静态块中初始化Map,而不是构造函数。

尝试

import java.util.Map; 
import java.util.HashMap; 

public enum EnumTest { 
  FOO, BAR, BAZ; 

  private static final Map<String,EnumTest> map = new LinkedHashMap<String,EnumTest>(); 
  static { 
      for(EnumTest e : EnumTest.values())
        map.put(e.name(), e); 
  } 

  public static void main(String... args) { 
    System.out.println(EnumTest.map); 
  } 
}

答案 1 :(得分:5)

难道你不能把地图的初始化放在Enum类型的静态初始化器中吗?

public enum SomeEnum
{
    Member1, Member2, Member3 ...

    private static Map<K, SomeEnum> map = ...;
    static 
    {
        ...populate map...
    }
    ...

编辑:问题似乎是Enum成员定义需要先行。我想我只是掩盖了这一点。我修复了这个例子。

答案 2 :(得分:3)

您可以在枚举类中引用某些内容。例如:

public class EnumTest {
  static final Map<String, MyEnum> map = new HashMap<String, MyEnum>();

  enum MyEnum {
    FOO, BAR, BAZ;

    MyEnum() {
      map.put(name(), this);
    }
  }
  static {
    // ensure MyEnum is initialized
    MyEnum.values();
  }

  public static void main(String[] argsa) {
    System.out.println(map.size());
  }
}

答案 3 :(得分:2)

似乎这就是为什么经常建议使用访问器方法而不是直接引用成员的原因。您的问题是代码允许在初始化之前访问地图。阻止对地图的任意访问,并将其隐藏在确保初始化的访问器方法后面。

import java.util.Map;
import java.util.HashMap;

public enum EnumTest {
  FOO, BAR, BAZ;

  private static Map<String,EnumTest> map = null;

  public synchronized static Map getMap() {
    if (map == null) {
      map = new HashMap<String,EnumTest>();
      for ( EnumTest e : EnumTest.values() ) {
        map.put( e.name(), e );
      }
    }

    return map;
  }

  public static void main(String[] args) {
    System.out.println( EnumTest.getMap().size() );
  }
}