如果Enums是摆脱编译时常量的答案,为什么语言设计者提供了让任意方法和字段在Enum上实现任意接口的工具?那些方法永远不会改变Enum实例的状态,或者它们可以吗?如果允许它们改变状态,那么Enum类型的不变量即导出一些常量的某种类型将破坏恕我直言。
答案 0 :(得分:3)
Java枚举实际上只是编译器和运行时需要特殊处理的类。所以是的,对枚举实例的方法调用肯定会改变它的状态。我不确定你的意思是“那么Enum类型的不变量,即导出一些常量的某种类型会破坏”。
谁说枚举只能是一堆常数?枚举类型的本质是您有一个预定义的固定数量的实例,您可以通过名称来引用它们 - 而Java枚举实现它。但是为什么一种语言不允许使用比这更强大的枚举?
如果你不想要额外的力量,没有人强迫你使用它。你可以拥有没有字段或方法的Java枚举,它们的行为与C枚举完全相同。
答案 1 :(得分:1)
枚举是编译时常量,但它们的成员不是。在运行时更改枚举成员通常不是一个好主意,但这是可能的。因此,您不能使用调用编译时常量的枚举成员(例如,在注释参数中)。
当你努力搞砸时,Java中的任何东西都是不变的。例如。 String常量包含char数组。数组不是一成不变的。下面是使用内联字符串常量可以实现的混乱的示例:
public static void main(final String[] args) throws Exception {
final Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
System.arraycopy("frog".toCharArray(), 0,
(char[]) valueField.get(Boolean.TRUE.toString()), 0, 4);
System.out.println(Boolean.parseBoolean("frog")); // true
System.out.println(Boolean.parseBoolean("true")); // false
}
因此,只要您的应用程序运行良好,大多数情况下Java常量只是常量。
答案 2 :(得分:0)
为什么语言设计者提供了让任意方法和字段以及在Enums上实现任意接口的工具
原因是允许用多态替换switch语句,并且通常允许在数据上定义方法,使程序更加面向对象。
搜索“类型安全的枚举模式”。 Java Enum是语言级别上此设计模式的实现。