所以我遇到了一些非常有用的东西。在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
构造函数的关系。
所以这让我想知道:与RAWR
类相比,Test
实际上是什么?通常情况下,这种语法会让我觉得我正在定义一个匿名的内部类,但这里看起来并不直观,因为RAWR
不是匿名的。
我能想到的最接近的事情是enum
的值实际上是enum
本身的扩展,例如,
public class RAWR extends Test {
@Override
public int doStuff() {
return 0;
}
}
那么,有没有人知道真正正在进行什么?
答案 0 :(得分:7)
枚举声明指定一个新的枚举类型,一种特殊的类类型。
[...]
枚举常量的可选类主体隐式定义了一个 匿名类声明(第15.9.5节),立即扩展 封闭枚举类型。
对于
c
声明正文中声明的每个枚举常量E
,E
隐式声明public static final field
类型为E
与c
同名。该字段具有可变初始值设定项 由c
组成,并使用与c
相同的注释进行注释。
您声明的enum
类型为Test
。你声明的每个枚举常量都是Test
的子类的实例,如果它有一个主体。
请注意,enum
类型也隐式final
(您无法将它们子类化)。 Java语言仅允许枚举常量的子类化行为。
答案 1 :(得分:1)
这是枚举的一个非常强大的功能,因为每个enum
不仅是一个完全成熟的类,可以有构造函数,设置器,getter等,但enum
的每个成员都可以拥有它拥有主枚举类的匿名实现。
答案 2 :(得分:1)
您实际上是在定义匿名内部类。在枚举的类文件上执行javap -c <classFile>
,以查看编译时枚举的外观。
您将看到枚举只不过是一个普通类,其公共静态最终变量与枚举类型相同。您还将看到为每个变量分配了一个匿名内部类。
示例:
$ 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
所以这不是最好的例子,因为没有任何枚举值实现一个方法,但你可能知道枚举实际是什么。
答案 3 :(得分:1)
如果您曾使用过enum
个泛型,则会遇到E extends Enum<E>
这是正确定义enum
类型的方法。这有点奇怪但是一旦你了解它,你就可以看到它说的是枚举实际上扩展了Enum
(注意不同的情况)。基本上是的,组中的所有enum
似乎扩展了基类声明类,但基本声明类实际上是Enum
- 排序。
BTW - 你也可以让enum
实现一个接口:
interface Something {
int getValue();
}
enum It implements Something {
One,
Two,
Three;
@Override
public int getValue() {
return ordinal();
}
}