枚举是否允许在 Java 中使用 setter?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15302188/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 19:10:02  来源:igfitidea点击:

Are enums allowed to have setters in Java?

javaenums

提问by user2149780

Question has been answered already. Thanks guys.

问题已经回答了。多谢你们。

I have an enum and it has parameters of Strings. Am I allowed to have setters for these variables?

我有一个枚举,它有字符串参数。我可以为这些变量设置 setter 吗?

public enum Blah {
    Monday("a"), Tuesday("b");
}

private final String letter;

Blah(String letter){
    this.letter = letter;
}

Am I allowed to do:

我是否可以这样做:

public String setLetter(String letter){
    this.letter = letter;
}

回答by Matt Ball

You need to remove the finalmodifier of the field in order for it to be settable:

您需要删除该final字段的修饰符才能对其进行设置:

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

http://ideone.com/QAZHol

Having mutable state in an enum is generally not recommended, however.

但是,通常不建议在枚举中具有可变状态。

回答by Taymon

This doesn't work because the field is marked as final.

这不起作用,因为该字段被标记为final

In principle, there is nothing preventing enums from having mutable fields. However, this is rarely if ever a good idea.

原则上,没有什么可以阻止枚举具有可变字段。然而,这很少是一个好主意。

回答by Jan Hornych

Update: It's possible to have setters in enum types.

更新:可以在枚举类型中使用 setter。

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
}

}

}

回答by Mona

During using Enumsit'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.

在使用过程中Enums,将变量声明为final.
由于在上面的示例中没有完成,我们可以将值设置为其他值。

By definition:
Enumsare just like any other class, with a predefined NonChanging/FIXEDset of instances.

根据定义:
Enums就像任何其他类一样,具有预定义的NonChanging/FIXED实例集。

回答by igor.zh

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.

允许,但是,如果您打算在多线程环境中使用枚举,请不要忘记,虽然 Java 枚举,实际上是一个延迟初始化的单例,在延迟初始化期间由 Java 保护(这意味着没有任何其他线程可以访问枚举直到初始化线程尚未完成初始化),无论如何不会防止同时使用 setter

So, in the OP's case of simple setter it is enough to declare the mutable field as volatile(remove finalof course):

因此,在 OP 的简单 setter 的情况下,将可变字段声明为volatilefinal当然是删除)就足够了:

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, synchronizedblocks, Locks might be needed.

在更复杂的情况下,如增量或其他(使用枚举极不可能,但是......谁知道,枚举 setter 本身就是一种奇特的东西)可能需要其他并发武器,如Atomics、synchronized块、Locks。

Also, there is a discussion on enum thread safety

此外,还有一个关于枚举线程安全的讨论

回答by Deepak

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
        }
}