这段代码:
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);
}
}
prints:
我就是价值
然而,这段代码:
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
Why can E.VALUE
创建在我看来是匿名的东西E
子类,覆盖toString
方法,同时使用最终类而不是隐式最终枚举会引发编译时错误?
更具体地说,为什么可以VALUE
覆盖任何内容E
?我的印象是代码
public enum E {
VALUE;
}
大致相当于
public static final class E {
public static final E VALUE = new E();
}
在这种情况下,匿名性质将不被允许。
有什么不同?为什么枚举很特殊?
根据JLS:
枚举类型是隐式最终类型,除非它至少包含一个枚举
具有类体的常量。
在你的例子中,VALUE
有一个类体,因此E
不是隐式最终的。
Edit:下面是一个验证该声明的简单示例:
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
Edit #2:虽然E
is not final
并且是子类VALUE
,明确尝试扩展它,例如class Foo extends E
or enum Bar extends E
是一个编译时错误8.1.4.超类和子类:
如果 ClassType 将类命名为 Enum 或
对它的任何调用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)