为什么类不能扩展枚举?

2022-09-03 12:15:23

我想知道为什么在Java语言中a不能扩展.classenum

我不是在谈论扩展一个(这不能完成,因为java没有多重继承,并且隐式扩展),而是一个类,它只是为了添加额外的方法,而不是额外的枚举值。enumenumenumjava.lang.Enumextendsenum

像这样:

enum MyEnum
{
    ASD(5),
    QWE(3),
    ZXC(7);
    private int number;
    private asd(int number)
    {
        this.number=number;
    }
    public int myMethod()
    {
        return this.number;
    }
}

class MyClass extends MyEnum
{
    public int anotherMethod()
    {
        return this.myMethod()+1;
    }
}

要这样使用:

System.out.println(MyClass.ASD.anotherMethod());

那么,任何人都可以为这个限制提供一个理由(或者给我指出正确的JLS部分)吗?


答案 1

您无法扩展 .它们隐含地。来自 JLS § 8.9enumfinal

枚举类型是隐式的,除非它包含至少一个具有类体的枚举常量。final

此外,来自 JLS §8.1.4 - 超类和子类

如果命名类或对它的任何调用,则为编译时错误。ClassTypeEnum

基本上,an 是一组枚举的预定义常量。因此,该语言允许您在 中使用枚举。例如,通过允许扩展它们,不会使它们符合开关情况的类型。除此之外,类的实例或其他扩展枚举的枚举也将是扩展枚举的实例。这基本上打破了s的目的。enumswitch-casesenum


答案 2

在 Java 1.5 之前的古代,你可能会做这样的枚举:

public class MyEnum {

public static final MyEnum ASD = new MyEnum(5);
public static final MyEnum QWE = new MyEnum(3);
public static final MyEnum ZXC = new MyEnum(7);

private int number;

private MyEnum(int number) {
    this.number = number;
}

public int myMethod() {
    return this.number;
    }

} 

关于这个数字有两件重要的事情:

  • 不允许从外部实例化类的私有构造函数
  • 实际的“枚举”值存储在静态字段中

即使你扩展它时它不是最终的,你也会意识到编译器需要一个显式构造函数,反过来又需要调用超级构造函数,这是不可能的,因为那个构造函数是私有的。另一个问题是,超类中的静态字段仍然存储该超类的对象,而不是扩展类的对象。我认为这可能是一个解释。