问题
I have an enum
and it has a parameter (field) that is a String
.
Am I allowed to have a setter for this field?
public enum Blah {
Monday("a"), Tuesday("b");
}
private final String letter;
Blah(String letter){
this.letter = letter;
}
Am I allowed to do the following?
public String setLetter(String letter){
this.letter = letter;
}
回答1:
You need to remove the final
modifier of the field in order for it to be settable:
public enum Blah {
Monday("a"), Tuesday("b");
private String letter;
private Blah(String letter){
this.letter = letter;
}
public void setLetter(String letter){
this.letter = letter;
}
}
http://ideone.com/QAZHol
Having mutable state in an enum is generally not recommended, however.
回答2:
This doesn't work because the field is marked as final
.
In principle, there is nothing preventing enums from having mutable fields. However, this is rarely if ever a good idea.
回答3:
Update: It's possible to have setters in enum types.
public class Main {
public enum Account {
ACCOUNT("NAME");
private String name;
private Account(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
System.out.println(Account.ACCOUNT.getName()); // print NAME
Account.ACCOUNT.setName("NEW");
System.out.println(Account.ACCOUNT.getName()); // print NEW
}
}
回答4:
During using Enums
it's always a good idea to declare variables as final
.
Since it is not done in the above example we are able to set the value to something else.
By definition:Enums
are just like any other class, with a predefined NonChanging/FIXED set of instances.
回答5:
public class EnumExample {
public enum Blah {
Monday("a"), Tuesday("b");
private String letter;
private Blah(String letter){
this.letter = letter;
}
public void setLetter(String letter){
this.letter = letter;
}
public String getLetter(){
return letter;
}
}
public static void main (String[] args) {
System.out.println("The Value of Monday is "+ Blah.Monday.getLetter());//prints a
System.out.println("The Value of Tuesday is "+Blah.Tuesday.getLetter());//prints b
}
}
回答6:
Allowed, but, if you are going to use the enum in multithreaded environment, please do not forget that although Java enum, effectively a lazy-initialized singleton, is guarded by Java during the lazy initialization (meaning here that no any other thread could access the enum until the initializing thread has not completed the initialization), it is not anyhow guarded against a concurrent use of the setter.
So, in the OP's case of simple setter it is enough to declare the mutable field as volatile
(remove final
of course):
volatile int letter;
In more complex cases like increments or others (highly unlikely with enums, but ... who knows, enum setter is itself an exotic thing) other concurrency weaponry like Atomic
s, synchronized
blocks, Lock
s might be needed.
Also, there is a discussion on enum thread safety
来源:https://stackoverflow.com/questions/15302188/are-enums-allowed-to-have-setters-in-java