这段代码:
public class Sandbox {
public enum E {
VALUE {
@Override
public String toString() {
return "I'm the value";
}
};
@Override
public String toString() {
return "I'm the enum";
}
}
public static void main(String[] args) {
System.out.println(E.VALUE);
}
}
打印:
I'm the value
但是,这段代码:
public class Sandbox {
public static final class C {
@Override
public String toString() {
return "I'm a C";
}
}
public static void main(String[] args) {
System.out.println(new C() {
@Override
public String toString() {
return "I'm anonymous";
}
});
}
}
导致编译错误:
cannot inherit from final HelloWorld.C
为什么 E.VALUE
可以创建在我看来是匿名的 E
子类,覆盖 toString
方法,同时使用 final类而不是隐式最终枚举会引发编译时错误?
更具体地说,为什么 VALUE
可以覆盖 E
中的任何内容?我的印象是代码
public enum E {
VALUE;
}
大致相当于
public static final class E {
public static final E VALUE = new E();
}
在这种情况下,匿名性质是不允许的。
有什么区别?为什么枚举很特别?
最佳答案
根据JLS :
An enum type is implicitly final unless it contains at least one enum constant that has a class body.
在您的示例中,VALUE
有一个类主体,因此 E
不是隐式最终的。
编辑:这是一个验证声明的简单示例:
import java.lang.reflect.Modifier;
public class Sandbox {
public enum E {
VALUE {};
}
public enum E2 {
VALUE;
}
public static void main(String[] args) {
System.out.println(E.class);
System.out.println(E.VALUE.getClass());
System.out.println("E.VALUE is subclass of E = " + E.VALUE.getClass().getSuperclass().equals(E.class));
System.out.println("E modifiers: " + Modifier.toString(E.class.getModifiers()));
System.out.println("E2 modifiers: " + Modifier.toString(E2.class.getModifiers()));
}
}
从输出中可以看出,编译器正在将 final
修饰符添加到 E2
而不是添加到 E
:
class Sandbox$E
class Sandbox$E$1
E.VALUE is subclass of E = true
E modifiers: public static
E2 modifiers: public static final
编辑#2:
尽管 E
不是 final
并且是 VALUE
的子类,但明确尝试扩展它,例如使用 class Foo extends E
或 enum Bar extends E
根据 8.1.4. Superclasses and Subclasses 是编译时错误:
It is a compile-time error if the ClassType names the class Enum or any invocation of it.
关于java - 为什么我可以匿名子类化枚举而不是最终类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16970615/