为什么Java枚举不能是final?

31
public interface Proposal  {  
    public static final enum STATUS { 
        NEW ,
        START ,
        CONTINUE ,
        SENTTOCLIENT
    }; 
}

Java不允许在接口内部将枚举声明为 final,但是默认情况下,接口中的每个数据成员都是 public static final。有谁能澄清这一点吗?


你是否认为“非 final”枚举可以被子类化? - Kirk Woll
我知道枚举不能被子类化,但Java允许我们在接口中的任何常量前写final,但不能在枚举前写,这为什么呢?这部分是我想问的(只是试图读懂他们在做这件事时的想法)。 - Zuned Ahmed
2
在类/接口(以及原则上的枚举)定义和成员字段定义(通常是接口中的“常量”)之间使用final有巨大的区别。一个影响子类可继承性,另一个影响可变性。 - Kirk Woll
4个回答

40

Java不允许您创建扩展enum类型的类。因此,枚举类型本身始终是final的,因此使用final关键字是多余的。

当然,从某种意义上说,enum并不是最终的,因为您可以为枚举描述符中的每个字段定义匿名子类。但是,使用final关键字来防止这些类型的描述没有太多意义,因为人们必须在相同的.java文件中创建这些子类,而任何具有该权限的人都可以轻松地删除final关键字。不存在其他包中的某个人扩展您的枚举的风险。


非常令人困惑的答案。如果您查看java.lang.Enum类的源代码,您会发现它不是final而是一个抽象类。 - Eugene Kuleshov
4
然而,所有的enum类型都不能被子类化。 - Louis Wasserman
8
Enum类是抽象的,因为你必须能够扩展它。但实际上扩展它的enum被编译器定义为final类。请参阅http://mindprod.com/jgloss/enum.html#UNDERTHEHOOD1。 - StriplingWarrior
4
java.lang.Enum 是抽象的,因为编译器将所有用 enum 关键字声明的枚举类型转换为 java.lang.Enum 类的子类。我来重新表述一下,以便更通俗易懂。 - Jai

33

枚举类型无法被声明为final,因为编译器会为每个程序员明确定义了实现的枚举条目生成子类。

此外,如果枚举类型中没有任何实例有自己的类体,则根据JLS第8.9节,它会被隐式地声明为final。


8

两个要点:

  1. 枚举是java.lang.Enum的最终子类
  2. 如果一个枚举是类的成员,它隐式地是静态的

2

声明枚举为final是没有意义的。对于类来说,final表示它们无法被继承。然而,默认情况下,枚举不能被继承(也就是说它们是final的)。

final关键字只适用于变量。然而,你应该将枚举看作数据类型而不是变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接