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类的静态字段。