枚举生成的类是 Final 还是 Not?

mat*_*ath 5 java enums extends code-generation final

当我指定这样的枚举时:

enum Color { RED }
Run Code Online (Sandbox Code Playgroud)

生成的代码javap -p Color如下所示:

final class Color extends java.lang.Enum<Color> {
  public static final Color RED;
  private static final Color[] $VALUES;
  public static Color[] values();
  public static Color valueOf(java.lang.String);
  private Color();
  private static Color[] $values();
  static {};
}
Run Code Online (Sandbox Code Playgroud)

但是,当我添加自定义扩展(例如显式构造函数)时,例如:

enum Color {
  RED,

  Color() {}
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

class Color extends java.lang.Enum<Color> {
  public static final Color RED;
  public static final Color Color;
  private static final Color[] $VALUES;
  public static Color[] values();
  public static Color valueOf(java.lang.String);
  private Color();
  private static Color[] $values();
  static {};
}
Run Code Online (Sandbox Code Playgroud)

缺少final生成的类 Color 的修饰符。但是,我无法扩展Color(像往常一样):

final class B extends Color {}
Run Code Online (Sandbox Code Playgroud)

编译器给出:

error: enum types are not extensible
final class B extends Color {}
      ^
1 error
Run Code Online (Sandbox Code Playgroud)

那么为什么final在向枚举类添加自定义代码时缺少修饰符呢?我想无论如何,防止子类化 Color 是通过编译器的健全性检查来执行的(又名:如果超类 typeof enum => 拒绝),对吗?

我在用OpenJDK 17.0.2

Swe*_*per 7

您没有在此处添加显式构造函数:

\n
enum Color {\n  RED,\n\n  Color() {}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

相反,您添加了另一个名为 的枚举常量Color其类主体为空。这在意想不到的线条中很明显javap

\n
public static final Color Color;\n
Run Code Online (Sandbox Code Playgroud)\n

因此,必须创建一个(空)匿名类,它继承自枚举类,作为枚举常量“ Color”的类。因此,枚举Color不能是最终的。你应该看到一个额外的Color$1.class您应该在 javac 输出文件夹中

\n

Java 语言规范中规定枚举是否应为最终枚举,如下所示:

\n
\n

枚举类要么是隐式最终的,要么是隐式密封的,如下所示:

\n
    \n
  • 如果枚举类的声明不包含具有类主体 (\xc2\xa78.9.1) 的枚举常量,则该枚举类是隐式最终的。
  • \n
  • [...]
  • \n
\n
\n

枚举Color具有具有主体的枚举常量Color,因此它不是final

\n

将构造函数添加到枚举的正确方法是使用 . 将其与常量分开;,用于分隔常数。例子:

\n
enum Color {\n  RED, GREEN, BLUE;\n\n  Color() {}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

正如预期的那样,这个Color枚举是final.

\n