wch*_*gin 11 java enums final anonymous-types
这段代码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
打印:
我很有价值
但是,这段代码:
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";
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
导致编译错误:
cannot inherit from final HelloWorld.C
Run Code Online (Sandbox Code Playgroud)
为什么可以E.VALUE创建我认为是匿名E子类的内容,覆盖该toString方法,而使用final类而不是隐式最终枚举会抛出编译时错误?
更具体地说,为什么可以VALUE覆盖任何东西E?我的印象是代码
public enum E {
VALUE;
}
Run Code Online (Sandbox Code Playgroud)
大致相当于
public static final class E {
public static final E VALUE = new E();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,不允许匿名性质.
有什么不同?为什么枚举很特别?
Dan*_*yMo 16
根据JLS:
枚举类型是隐式final的,除非它包含至少一个具有类主体的枚举常量.
在您的示例中,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()));
}
}
Run Code Online (Sandbox Code Playgroud)
您可以从输出中看到编译器正在添加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
Run Code Online (Sandbox Code Playgroud)
编辑#2:
即使E是不 final和由子类VALUE,明确地试图把它扩大,如用class Foo extends E或者enum Bar extends E是根据编译时错误8.1.4.超类和子类:
如果ClassType命名类Enum或对其进行任何调用,则为编译时错误.
小智 5
我想如果比较类和枚举,那么可以将枚举E与类进行比较,并且可以将枚举值VALUE与匿名实例进行比较.因此,您的第一个示例可以重写如下:
public class Sandbox {
public static class E {
public static final E VALUE = new E() {
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1274 次 |
| 最近记录: |