【问题标题】:switch over value of enum: case expressions must be constant expressions切换枚举值:case 表达式必须是常量表达式
【发布时间】:2014-08-07 13:23:59
【问题描述】:

我有一个具有以下结构的枚举:

public enum Friends {
    Peter("Peter von Reus", "Engineer"),
    Ian("Ian de Villiers", "Developer"),
    Sarah("Sarah Roos", "Sandwich-maker");

    private String fullName;
    private String occupation;

    private Person(String fullName, String occupation) {
        this.fullName = fullName;
        this.occupation = occupation;
    }

    public String getFullName() {
        return this.fullName;
    }

    public String getOccupation() {
        return this.occupation;
    }
}

我现在想使用switch 来确定变量name 是否与某个enum 相关联:

//Get a value from some magical input
String name = ...

switch (name) {
    case Friends.Peter.getFullName():
        //Do some more magical stuff
        ...
    break;
    case Friends.Ian.getFullName():
        //Do some more magical stuff
        ...
    break;
    case Friends.Sarah.getFullName():
        //Do some more magical stuff
        ...
    break;
}

这对我来说似乎完全合法,但我在 Eclipse 中收到错误 case expressions must be constant expressions。 我可以通过一组简单的 if 语句来解决这个问题,但我想知道这个错误的原因以及如果允许的话事情会如何发展。

注意:我无法更改Friends 的结构

【问题讨论】:

    标签: java enums switch-statement


    【解决方案1】:

    如果我理解你的问题,你可以使用valueOf(String)like

    String name = "Peter";
    Friends f = Friends.valueOf(name);
    switch (f) {
    case Peter:
        System.out.println("Peter");
        break;
    case Ian:
        System.out.println("Ian");
        break;
    case Sarah:
        System.out.println("Sarah");
        break;
    default:
        System.out.println("None of the above");
    }
    

    还有,这个

    private Person(String fullName, String occupation) {
        this.fullName = fullName;
        this.occupation = occupation;
    }
    

    应该是

    private Friends(String fullName, String occupation) {
        this.fullName = fullName;
        this.occupation = occupation;
    }
    

    因为Person != Friends。

    编辑

    根据您的评论,您需要编写一个静态方法来获取正确的Friends 实例,

        public static Friends fromName(String name) {
            for (Friends f : values()) {
                if (f.getFullName().equalsIgnoreCase(name)) {
                    return f;
                }
            }
            return null;
        }
    

    然后你可以调用它,

        String name = "Peter von Reus";
        Friends f = Friends.fromName(name);
    

    valueOf(String) 将匹配枚举字段的名称。所以“伊恩”、“莎拉”或“彼得”。

    【讨论】:

    • 不,因为名字是“Peter von Reus”,而不是“Peter”。
    • @ElliottFrisch 为什么可以访问 case 语句中的枚举成员,而无需在其前面添加枚举名称(PETER 而不是 FRIENDS.PETER)?
    • 因为静态方法在枚举中。
    【解决方案2】:

    这对我来说似乎完全合法

    它不是——方法调用从不是一个常量表达式。请参阅 JLS 15.28 了解常量表达式的构成。而且 case 值必须是一个常量表达式。

    最简单的解决方法是使用Friend.fromFullName 静态方法,它可能在HashMap<String, Friend> 中查找Friend。 (当然,您必须在Friend 中使用该方法......这只是最传统的地方。)然后您可以切换枚举而不是名称。

    作为旁注,您的枚举名称应该是单数形式,并带有ALL_CAPS 成员,所以Friend.PETER 等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      相关资源
      最近更新 更多