java 切换枚举值:case 表达式必须是常量表达式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25183754/
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-11-02 07:32:17  来源:igfitidea点击:

switch over value of enum: case expressions must be constant expressions

javaenumsswitch-statement

提问by Ian2thedv

I have an enum with the following structure:

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

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

I would now like to use switchto determine, if a variable nameis associated with a certain enum:

我现在想用以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;
}

This seems perfectly legal to me, but I'm getting the error case expressions must be constant expressionsin Eclipse. I can get around this with a simple set of if statements but I would like to know the reason for this error and how things might go south if this was allowed.

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

NOTE: I cannot change the structure of Friends

注意:我不能改变结构 Friends

回答by Elliott Frisch

If I understand your question, you can use valueOf(String)like

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

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");
}

Also, this

还有,这

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

Should be

应该

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

Because Person!= Friends.

因为Person!= Friends

Edit

编辑

Based on your comment, you will need to write a static method to get the correct Friendsinstance,

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

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

Then you can call it with,

然后你可以调用它,

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

valueOf(String)will match the name of the enum field. So "Ian", "Sarah" or "Peter".

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

回答by Jon Skeet

This seems perfectly legal to me

这对我来说似乎完全合法

Well it's not - a method call is nevera constant expression. See JLS 15.28for what constitutes a constant expression. And a case value always has to be a constant expression.

好吧,它不是 - 方法调用从来都不是常量表达式。请参阅JLS 15.28了解什么是常量表达式。并且 case 值必须始终是一个常量表达式。

The simplest fix would be to have a Friend.fromFullNamestatic method, which perhaps looked the Friendup in a HashMap<String, Friend>. (You don't haveto have that method in Friendof course... it's just that would be the most conventional place.) Then you could switch over the enum rather than the name.

最简单的解决方法是使用Friend.fromFullName静态方法,它可能FriendHashMap<String, Friend>. (你不具备有这种方法中Friend,当然......它只是将是最传统的地方。)然后,你可以在枚举切换而不是名称。

As a side note, your enum name should be in the singular and with ALL_CAPSmembers, so Friend.PETERetc.

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