考虑一下这个例子:
enum SomeEnum {
VALUE1("value1"),
VALUE2("value2"),
VALUE3("value3")
;
private String value;
private SomeEnum(final String value) {
this.value = value;
}
//toString
public String toString() {
return value;
}
}
我们怎么能这样做(以及真的值的变化)?
SomeEnum.VALUE1.value = "Value4";
System.out.println(SomeEnum.VALUE1);
这个枚举实例是否隐式静态和最终?此外,由于value
是private
,为什么我可以在其他类之外访问它?
答案 0 :(得分:20)
似乎没有人解决私人问题。我的猜测是你从一个包含类型访问私有字段 - 你的枚举实际上是一个嵌套类型,如下所示:
class Test
{
static void Main() {
// Entirely valid
SomeEnum.VALUE1.value = "x";
}
enum SomeEnum {
VALUE1("value1");
private String value;
private SomeEnum(final String value) {
this.value = value;
}
}
}
这完全合法且正常 - 您可以始终从包含类型访问嵌套类型的私有成员。
如果您将枚举设为顶级类型,则不会看到此内容。
至于改变价值观 - 正如其他人所说的那样,VALUE1
是隐含的静态和最终的,但这并不能阻止你改变VALUE1.value
。同样,这完全符合Java在其他地方的工作方式 - 如果您有一个List
类型的静态字段,您仍然可以向其添加条目,因为它不会修改字段本身。
如果您想让SomeEnum
正确不变,请制作value
字段final
。
答案 1 :(得分:5)
你做不到
SomeEnum.VALUE1 = "Value4";
System.out.println(SomeEnum.VALUE1);
但你可以做到
SomeEnum.VALUE1.value = "Value4";
System.out.println(SomeEnum.VALUE1);
和value
确实发生了变化,但不是静态最终 VALUE1 。
此外,由于值是私有的,为什么我可以在其他类之外访问它?
您可以访问外部/内部类中的私有字段,但我找不到可以从其他类访问它的示例(例如,在同一个包中)。
答案 2 :(得分:2)
这个枚举实例是不是隐式静态和最终的?
不。在您的示例中,value
等枚举实例的成员可以是可变的。
(对您的示例中的实例(SomeEnum.VALUE1
等)的引用是最终的和静态的。
此外,由于值是私有的,为什么我可以在其他类之外访问它?
你做不到。 enum
是具有可枚举实例数的“类”。就是这样。
VALUE1
是“类”SomeEnum
的一个实例,因此SomeEnum.VALUE1.value
是一个普通字段,与其他字段一样。
当你这样做时
System.out.println(SomeEnum.VALUE1);
您调用访问SomeEnum.VALUE1.toString
字段的value
。您没有立即访问value
字段。
// Not possible since field is private.
System.out.println(SomeEnum.VALUE1.value);
答案 3 :(得分:2)
这个枚举实例是否隐式静态和最终?
Enum实例具有这些特征。但没有人说,这些实例是{em> immutable ,如Integer
或String
。所以你可以修改这些值。
这并不意味着这是推荐的做法!事实并非如此。
修改强>
再解释一下:
“Enum隐式静态”表示:
enum Foo { FOO };
这里FOO
是静态的,虽然普通 Java语法会提示,FOO
是一个错误地命名为常量的实例变量。您也可以像静态变量一样访问它。
“Enum隐含最终”意味着:
enum Foo { FOO, BAR };
Foo.FOO = Foo.BAR;
是不允许的。存储在FOO
中的参考无法更改。您也无法创建新的实例。
“枚举不隐式不可变”意味着:Foo.FOO
会给你一个对象。标准对象。如果对象允许修改自己的内容 - 那就是。这不是禁止的。
答案 4 :(得分:1)
枚举本身(VALUE1
,VALUE2
和VALUE3
)是静态的和最终的。它们是SomeEnum
类型的三个实例,我们无法更改它们(例如从枚举中删除VALUE1
或在运行时添加VALUE4
)。
但我们可以向实例添加公共字段(如示例中所示)并在运行时更改这些字段的内容。
答案 5 :(得分:1)
SomeEnum.VALUE1 =" Value4" ......实际上不起作用。
更重要的是,VALUE1将始终仅等于VALUE1而不是VALUE2或VALUE3,与其成员值无关。