java Java中枚举类型的强制初始化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3818026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Force Initialization of an enumerated type in Java
提问by Ryan Delucchi
I am attempting to find a way to force Java to load/initialize an enumerated type (which is nested within a class that contains a static Map).
我试图找到一种方法来强制 Java 加载/初始化枚举类型(它嵌套在包含静态 Map 的类中)。
This is important to me because the enumerated type has a constructor that populates said map, and without an explicit way to initialize this enum, the map will remain empty. I have attempted to use Class.forName, but this does not seem to work.
这对我很重要,因为枚举类型有一个构造函数来填充所述映射,如果没有明确的方法来初始化这个枚举,映射将保持为空。我曾尝试使用Class.forName,但这似乎不起作用。
I suppose I could create an instance of the enum (and store it in soem other collection or something), but I would like to know if there is an elegant way to do this.
我想我可以创建一个枚举实例(并将它存储在其他集合或其他东西中),但我想知道是否有一种优雅的方法来做到这一点。
采纳答案by Peter Lawrey
A class is loaded when you reference a class. This works the same for all classes.
当您引用一个类时,就会加载一个类。这对所有类都一样。
The problem you have is more likely to be that an Enum value is initialised before any static block. i.e. you cannot refer to something initialise in a static block in a constructor. (Generally initialising static content in a constructor is a BAD idea) You need to initialise the Map in the static block, not the constructor.
您遇到的问题更有可能是在任何静态块之前初始化 Enum 值。即你不能在构造函数的静态块中引用初始化的东西。(通常在构造函数中初始化静态内容是一个坏主意)您需要在静态块中初始化 Map,而不是在构造函数中。
Try
尝试
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);
}
}
回答by Matt H
Can't you just put initialization of the map in the static initializer of the Enum type?
你不能把映射的初始化放在 Enum 类型的静态初始化器中吗?
public enum SomeEnum
{
Member1, Member2, Member3 ...
private static Map<K, SomeEnum> map = ...;
static
{
...populate map...
}
...
EDIT: It appears that the issue was that the Enum member definitions need to come first. I guess I just glossed over this. I fixed the example.
编辑:问题似乎是 Enum 成员定义需要首先出现。我想我只是掩盖了这一点。我修正了这个例子。
回答by Laurence Gonsalves
You can just reference something in the enum class. For example:
您可以只引用枚举类中的某些内容。例如:
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());
}
}
回答by Dave Costa
Seems like this is exactly why it is often recommended to use accessor methods instead of directly referencing members. Your problem is that the code allows access to the map before it is initialized. Block arbitrary access to the map, and hide it behind an accessor method that makes sure it is initialized.
似乎这正是为什么经常建议使用访问器方法而不是直接引用成员的原因。您的问题是代码允许在初始化之前访问地图。阻止对地图的任意访问,并将其隐藏在确保它已初始化的访问器方法之后。
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() );
}
}

