枚举构造函数必须是私有或包默认值,并且不允许使用受保护或公共访问修饰符。为什么这样
问问题
5218 次
4 回答
5
因为根据定义,枚举具有一组固定的实例,这些实例在枚举本身中声明和构造。因此,从枚举类本身外部使用构造函数是没有意义的。
而且 AFAIK,枚举构造函数始终是显式或隐式私有的。
于 2012-07-11T14:59:55.293 回答
3
于 2012-07-11T14:58:37.940 回答
1
枚举并不意味着(由您)实例化。
http://docs.oracle.com/javase/tutorial/reflect/special/enumTrouble.html:
提示:尝试显式实例化枚举是编译时错误,因为这会阻止定义的枚举常量是唯一的。此限制也在反射代码中强制执行。尝试使用其默认构造函数实例化类的代码应首先调用 Class.isEnum() 以确定该类是否为枚举。
于 2012-07-11T14:58:24.023 回答
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 或其他东西)。
于 2012-07-11T15:58:04.590 回答