Are enums allowed to have setters in Java?

喜你入骨 提交于 2020-08-26 21:29:53

问题


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 Atomics, synchronized blocks, Locks 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!