Java 枚举内部类未被识别为枚举

Java 枚举内部类未被识别为枚举,java,enums,inner-classes,Java,Enums,Inner Classes,考虑以下枚举类: public enum APlanet { VENUS () {public void stuff(){}}, EARTH () {public void stuff(){}}, MARS () {public void stuff(){}}; public abstract void stuff(); } public enum BPlanet { VENUS (), EARTH (), MA

考虑以下枚举类:

public enum APlanet {
    VENUS   ()  {public void stuff(){}},
    EARTH   () {public void stuff(){}},
    MARS    ()  {public void stuff(){}};
    public abstract void stuff();
}

public enum BPlanet {
    VENUS   (),
    EARTH   (),
    MARS    ();
}
然后
APlanet.MARS.getClass().isEnum()
返回false,而
BPlanet.MARS.getClass().isEnum()
返回true。为什么? 请注意,
APlanet.getDeclaringClass().isEnum()
正确返回true

具体来说,我正在尝试可靠地测试对象是否为枚举:

Object a = APlanet.MARS;
Object b = BPlanet.MARS;
a.getClass().isEnum() /* returns false */
b.getClass().isEnum() /* returns true  */
然而

内部类APlanet.MARS不是枚举,但您可以将其分配给枚举,这有点令人困惑,如中所示:

Enum<?> m = APlanet.MARS;
Enum=APlanet.MARS;
来自:

枚举常量的可选类主体隐式定义了一个匿名类声明(§15.9.5),该声明扩展了立即封闭的枚举类型。类主体由匿名类的常规规则管理;特别是它不能包含任何构造函数

您已在第一个枚举中声明了特定于常量的类主体:

 MARS ()  {public void stuff(){}}; // The curly braces defines a class body
这将创建一个匿名类。因此,
MARS.getClass()
将返回此匿名类的类实例,该类不是
Enum


这类似于您创建接口的匿名子类的实例或任何其他类似的类的情况:

SomeInterface obj = new SomeInterface() { /** Method definitions **/ };
然后,
obj.getClass()
将不会返回
SomeInterface
,而是,
类包含声明$1

请注意,
APlanet.getDeclaringClass().isEnum()
正确返回true

我猜想应该是-
APlanet.MARS.getDeclaringClass().isEnum()
。根据方法的文档,该值将返回true:

返回与此枚举常量的枚举类型对应的类对象。当且仅当
e1.getDeclaringClass()==e2.getDeclaringClass()
时,两个枚举常量e1和e2具有相同的枚举类型。(此方法返回的值可能不同于具有常量特定类主体的枚举常量的
Object.getClass()
方法返回的值。)


但我认为枚举不能被子类化? 现在,人们可能会怀疑,
enum
不能被子类化。那么,如何创建enum的匿名子类呢?它如何扩展
枚举
?这是因为,枚举是最终的,除非它声明了某个特定于常量的类主体,如下所示:

枚举类型是隐式最终类型,除非它至少包含一个具有类主体的枚举常量

您仍然无法显式扩展
枚举
: 即使特定于常量的类主体隐式创建了一个匿名子类,也不能显式扩展
enum
。根据:

如果类类型命名类枚举或调用它,则这是编译时错误


+1.一切又开始了:)。恭喜你成为“传奇人物”@波希米亚人。啊!!谢谢:)非常高兴。谢谢你的快速回复。如何可靠地测试对象是否是枚举实例?这是什么意思?你能举个例子吗?如果你需要做这样的事情,那么我想你的设计有问题。
SomeInterface obj = new SomeInterface() { /** Method definitions **/ };