枚举构造函数必须是私有或默认包,并且不允许使用受保护或公共访问修饰符。为什么这样
答案 0 :(得分:5)
因为根据定义,枚举具有一组固定的实例,这些实例在枚举本身中声明和构造。因此,从枚举类本身外部使用构造函数是没有意义的。
AFAIK,一个枚举构造函数总是,显式或隐含地,是私有的。
答案 1 :(得分:3)
枚举类型的构造函数必须是包私有或私有访问。它会自动创建在枚举主体开头定义的常量。你不能自己调用枚举构造函数。
能够创建枚举的新实例是没有意义的,所以语言阻止你这样做!
答案 2 :(得分:1)
Enum并不意味着(由你)实例化。
http://docs.oracle.com/javase/tutorial/reflect/special/enumTrouble.html:
提示:尝试显式实例化枚举是一个编译时错误,因为这会阻止定义的枚举 不变的常数。这个限制也在强制执行 反思代码。尝试使用实例化类的代码 它们的默认构造函数应首先调用Class.isEnum() 确定该类是否为枚举。
答案 3 :(得分:0)
无法动态扩展枚举的原因是实例化的值被编译为Class对象的字节码:
public T[] getEnumConstants()
Returns the elements of this enum class or null if this Class object does not
represent an enum type.
因此,任何构造新实例的尝试都无法传递到实际的Class,因为无法更改Class对象。如果你想要这种行为,你必须自己模拟它,并给它一些独特的值来表示每一个,然后有一个序数计数器,最后一个静态地图(或其他一些结构)来保存所有的值
public class MyEnum {
private static AtomicInteger nextOrdinal = new AtomicInteger(0);
private static Map<Integer, MyEnum> instances =
new HashMap<Integer, MyEnum>();
private int ordinal;
private String name;
public MyEnum(String name) {
super();
this.ordinal = nextOrdinal.incrementAndGet();
this.name = name;
instances.put(Integer.valueOf(this.ordinal), this);
}
public String name() {
return name;
}
public int ordinal() {
return ordinal;
}
public static Set<MyEnum> getEnumConstants() {
return Collections.unmodifiableSet(instances.values());
}
public static MyEnum fromInt(int ordinal) {
return instances.get(Integer.valueOf(ordinal));
}
public static MyEnum fromString(String name) {
for (MyEnum val : instances.values()) {
if (val.name().equals(name)) {
return val;
}
}
return null;
}
}
您可能还需要.equals和.hashcode方法,以及防止同一名称被多次使用(您可以在构造函数中执行此操作并抛出IllegalStateException或者如果您的名称重复)。