为什么Enum构造函数不能具有protected或public访问修饰符

时间:2012-07-11 14:56:48

标签: java enums

枚举构造函数必须是私有或默认包,并且不允许使用受保护或公共访问修饰符。为什么这样

4 个答案:

答案 0 :(得分:5)

因为根据定义,枚举具有一组固定的实例,这些实例在枚举本身中声明和构造。因此,从枚举类本身外部使用构造函数是没有意义的。

AFAIK,一个枚举构造函数总是,显式或隐含地,是私有的。

答案 1 :(得分:3)

来自Java tutorial

  

枚举类型的构造函数必须是包私有或私有访问。它会自动创建在枚举主体开头定义的常量。你不能自己调用​​枚举构造函数。

能够创建枚举的新实例是没有意义的,所以语言阻止你这样做!

答案 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或者如果您的名称重复)。