有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

是否允许枚举在Java中具有setter?

我有一个enum,它有一个参数(字段)是String。 我可以在这个领域有一个二传手吗

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

private final String letter;

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

我可以做以下事情吗

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

共 (6) 个答案

  1. # 1 楼答案

    您需要删除字段的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

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

  2. # 2 楼答案

    在使用Enums期间,最好将变量声明为final
    由于在上面的示例中没有这样做,我们可以将该值设置为其他值

    根据定义:
    Enums与任何其他类一样,具有预定义的非更改/固定的实例集

  3. # 3 楼答案

    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
            }
    }
    
  4. # 4 楼答案

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

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

  5. # 5 楼答案

    更新:可以在枚举类型中使用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
    }
    

    }

  6. # 6 楼答案

    允许,但是,如果您打算在多线程环境中使用enum,请不要忘记,尽管Java enum实际上是一个惰性初始化的单例, 在延迟初始化期间由Java保护 (这里的意思是,在初始化线程尚未完成初始化之前,任何其他线程都无法访问枚举), 无论如何,它都不能防止同时使用setter

    因此,在OP的简单setter示例中,将可变字段声明为volatile(当然,删除final)就足够了:

    volatile int letter;
    

    在更复杂的情况下,如增量或其他情况(enum不太可能,但…谁知道,enum setter本身就是一个异国事物)可能需要其他并发武器,如Atomics、synchronized块、Locks

    还有a discussion on enum thread safety