为什么不从Enum扩展<e extends =“”enum <e =“”>&gt; </e>

时间:2012-04-10 08:14:17

标签: java enums

我偶然发现了以下问题:我无法从Java 1.5中定义的这个类扩展和实现(java.lang包)

public abstract class Enum<E extends Enum<E>> {...
}..

我遇到的问题是创建自己的枚举类型,它具有不同的序数值。我不想通过使用不同的序数名称来实现它,比如getCode()等。所以我想我可以继续扩展上面的类。

public final class XYZ extends Enum<XYZ> { //Does not work.
  //
  A("A", 1),
  B("B", 7);
  .
}

我知道我可以做到以下几点:

public enum NEWEnum {
   A(1),
   B(7);

   private int code;
   private NEWEnum(int code) {
     this.code = code;
   }
   public int getCode() {
     return this.code;
   }
}

我宁愿在Enum中使用通常的命令,如ordinal()和name()。

5 个答案:

答案 0 :(得分:5)

你无法像这样扩展Enum。它内置于编译器或运行时(不确定是哪个)。

但看起来你正试图解决错误的问题;枚举值的序数不应该具有任何功能意义。只要你给它一个,它应该有一个不同于'Ordinal'的名字。您的第二个代码段远远优于您的第一个。

一般来说,依靠序数来做任何事都是不好的做法;它可能永远不应该首先暴露出来。您唯一可以依赖的是名称和您自己分配的任何价值。

如果您将字段命名为“序数”非常重要,请使用typesafe enum pattern (item 21),这只是Enum的实现。

答案 1 :(得分:4)

Enum得到编译器的特殊处理,像EnumSet这样的类根据这种处理做出假设。像ordinal()name()这样的Enum方法的行为是严格定义的,并且自己实现它们来复制这种行为是没有意义的。此外,声明枚举值的语法仅在enum中有效,并且不会在class中编译。

重要的是要记住,你不应该自己使用ordinal(),因此根据你的问题定义它是没有意义的。

答案 2 :(得分:1)

Enum类在Java中很特殊,因为它用于实现Enum语言功能。因此,它不仅仅是像Java中的任何其他类一样的类,而是更加特殊(如String+运算符被重载,或者像盒装类一样)。要使这些功能起作用,枚举需要特殊要求(例如,我猜,连续的序数)。因此,Java语言规范explicitly forbids手动继承自Enum类。

答案 3 :(得分:0)

枚举在语言核心和特殊用途中具有特殊含义。因此,您可以在switch语句中使用它们,这在普通类中是不可能的。

答案 4 :(得分:0)

例如,如果显式实现它,则不必在构造函数中初始化“name”和“ordinal”属性。它可能会导致NPE。