Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are enums allowed to have setters in Java?

Tags:

java

enums

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;
}
like image 284
user2149780 Avatar asked Mar 08 '13 19:03

user2149780


3 Answers

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 Atomics, synchronized blocks, Locks might be needed.

Also, there is a discussion on enum thread safety

like image 115
igor.zh Avatar answered Oct 21 '22 04:10

igor.zh


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.

like image 36
Taymon Avatar answered Oct 21 '22 04:10

Taymon


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
}

}

like image 36
Jan Hornych Avatar answered Oct 21 '22 04:10

Jan Hornych