Java 枚举值实际上是枚举本身的子类吗?

Java 枚举值实际上是枚举本身的子类吗?,java,class,enums,Java,Class,Enums,所以我遇到了一些有趣的东西,非常有用。在enum中,可以定义一个abstract方法,强制每个enum值为其提供实现。例如,以下各项: public enum Test { RAWR ("Burninating the country side") { @Override public int doStuff() { return 0; } }; private final String enum

所以我遇到了一些有趣的东西,非常有用。在
enum
中,可以定义一个
abstract
方法,强制每个
enum
值为其提供实现。例如,以下各项:

public enum Test {

    RAWR ("Burninating the country side") {
        @Override
        public int doStuff() {
            return 0;
        }
    };

    private final String enumStuff;

    private Test(String enumStuff) {
        this.enumStuff = enumStuff;
    }

    public abstract int doStuff();

}
我添加了private变量,以便您可以看到它与标准
private
构造函数的关系

这让我想知道:
RAWR
实际上是什么,与
Test
类有关?通常,这种语法会让我认为我正在定义一个匿名的内部类,但这在这里似乎并不直观,因为
RAWR
绝不是匿名的

我能想到的最接近的事情是
enum
的值实际上是
enum
本身的扩展,例如

public class RAWR extends Test {
    @Override
    public int doStuff() {
        return 0;
    }
}
那么,有人知道这到底是怎么回事吗?

枚举声明指定一种新的枚举类型,一种特殊的类类型。

[……]

枚举常量的可选类主体隐式定义 匿名类声明(§15.9.5),立即扩展 封闭枚举类型

对于
E
声明正文中声明的每个枚举常量
c
E
具有类型为
E
的隐式声明的
公共静态最终字段
c
同名。该字段有一个变量初始值设定项 由
c
组成,并由与
c
相同的注释进行注释

您声明的
enum
类型是
Test
。您声明的每个枚举常量都是
Test
子类的实例(如果它有一个主体)


请注意,
enum
类型也是隐式的
final
(您将无法对它们进行子类化)。Java语言只允许枚举常量的这种子类化行为。

这是枚举的一个非常强大的功能,因为每个
enum
都是一个成熟的类,可以有构造函数、setter、,getter等,但是
枚举的每个成员都可以有自己的主枚举类的匿名实现。

您实际上是在定义匿名内部类。在枚举的类文件上执行
javap-c
,查看编译时枚举的外观

您将看到,枚举只不过是一个普通类,它具有与枚举相同类型的公共静态最终变量。您还将看到,为每个变量分配了一个匿名内部类

例如:

$ javap-c StatusCode.class

public final class de.haufe.StatusCode extends java.lang.Enum<de.haufe.StatusC                                                                                        ode> {
    public static final de.haufe.StatusCode CREATED;

    public static final de.haufe.StatusCode BAD_REQUEST;

    public static final de.haufe.StatusCode UNAUTHORIZED;

    public static final de.haufe.StatusCode NOT_FOUND;

    public static final de.haufe.StatusCode PRECONDITION_FAILED;

    public static final de.haufe.StatusCode UNSUPPORTED_MEDIA_TYPE;

    public static final de.haufe.StatusCode UNPROCESSABLE_ENTITY;

    public static final de.haufe.StatusCode LOCKED;

    public static final de.haufe.StatusCode INTERNAL_SERVER_ERROR;

    public static de.haufe.StatusCode[] values();
}

// more stuff
$javap-c StatusCode.class
公共最终类de.haufe.StatusCode扩展了java.lang.Enum{
创建公共静态最终de.haufe.StatusCode;
公共静态最终de.haufe.StatusCode错误请求;
公共静态最终de.haufe.StatusCode未经授权;
未找到公共静态最终de.haufe.StatusCode;
公共静态最终de.haufe.StatusCode前置条件_失败;
公共静态最终de.haufe.StatusCode不支持\u媒体\u类型;
公共静态最终de.haufe.StatusCode不可处理实体;
公共静态最终de.haufe.StatusCode锁定;
公共静态最终de.haufe.StatusCode内部服务器错误;
公共静态de.haufe.StatusCode[]值();
}
//更多的东西

因此,这不是最好的例子,因为没有一个枚举值实现一个方法,但您可能知道枚举实际上是什么。

如果您曾经在泛型中使用过
enum
s,您会遇到
E extensed enum
,这是定义
enum
类型的正确方法。这有点奇怪,但一旦你开始思考它,你就会发现它是在说枚举实际上扩展了自己的
enum
(注意不同的情况)。因此本质上是的,组中的所有
enum
s似乎扩展了基本声明类
,但基本声明类实际上是
enum

顺便说一句-您还可以使
enum
s实现一个接口:

interface Something {
    int getValue();
}

enum It implements Something {
    One,
    Two,
    Three;

    @Override
    public int getValue() {
        return ordinal();
    }
}

这意味着
enum
值已经是一个类了,对吗?否则就不可能从中创建匿名类。那么,这些值扩展了基本
enum
类,对吗?@jeff抱歉,我不得不离开我的电脑。让我为您找到JLS中的引用。每个常量都隐式地是enum类的静态字段。