Consider the example:
enum SomeEnum {
VALUE1(\"value1\"),
VALUE2(\"value2\"),
VALUE3(\"value3\")
;
private String value;
private SomeEnu
SomeEnum.VALUE1 = "Value4" ... actually does not work.
More important, VALUE1 will always only be equal to VALUE1 and not VALUE2 or VALUE3, independent of it's member value.
Isn't that enum instance(s) are implicitly static and final?
The Enum instances have these traits. But no one said, these instances are immutable like Integer
or String
. So you can modify the values.
That does not mean that this is recommended practice! It isn't.
Edit
To explain a little more:
"Enum implicitly static" means:
enum Foo { FOO };
Here FOO
is static, although the normal Java syntax would suggest, that FOO
is an instance variable wrongly named like a constant. You also access it like a static variable.
"Enum implicitly final" means:
enum Foo { FOO, BAR };
Foo.FOO = Foo.BAR;
is not allowed. The reference stored in FOO
cannot be changed. You also cannot create new instances.
"Enum not implicitly immutable" means: Foo.FOO
will give you an object. A standard object. If the object allows modifications of its own content - so it be. This is not forbidden.
No-one seems to have addressed the private aspect. My guess is that you're accessing the private field from a containing type - that your enum is actually a nested type, like this:
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;
}
}
}
That's entirely legitimate and normal - you can always access private members of a nested type from the containing type.
If you make the enum a top-level type, you won't see this.
As for changing values - as everyone else has said, VALUE1
is implicitly static and final, but that doesn't stop you from changing VALUE1.value
. Again, this is entirely in accordance with how Java works elsewhere - if you have a static field of type List
, you can still add entries to it, because that's not modifying the field itself.
If you want to make SomeEnum
properly immutable, make the value
field final
.
You can't do
SomeEnum.VALUE1 = "Value4";
System.out.println(SomeEnum.VALUE1);
but you can do
SomeEnum.VALUE1.value = "Value4";
System.out.println(SomeEnum.VALUE1);
and value
really changes, but not the static final VALUE1.
Also, since value is private, why can I access it outside other classes?
You can access a private field in an outer/inner class, but I cannot find an example of where you can access it from another class (in the same package for example).
The enums itself (VALUE1
, VALUE2
and VALUE3
) are static and final. They are three instances of the SomeEnum
type and we can't change them (like deleting VALUE1
from the enum or adding a VALUE4
at runtime).
But we can add public fields to the instances (like in your example) and alter the content of those fields at runtime.
Isn't that enum instance(s) are implicitly static and final?
Nope. Members of enum-instances such as value
in your example can be mutable.
(The references to the instances (SomeEnum.VALUE1
etc in your example) are final and static though.
Also, since value is private, why can I access it outside other classes?
You can't. An enum
is a "class" with an enumerable number of instances. That's all.
VALUE1
is in this case a an instance of the "class" SomeEnum
, thus SomeEnum.VALUE1.value
is an ordinary field like any other.
When you do
System.out.println(SomeEnum.VALUE1);
you invoke SomeEnum.VALUE1.toString
which accesses the value
field. You're not accessing the value
-field immediately.
// Not possible since field is private.
System.out.println(SomeEnum.VALUE1.value);