简体   繁体   English

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

[英]switch over value of enum: case expressions must be constant expressions

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 switch to determine, if a variable name is 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 expressions in Eclipse. 这对我来说似乎是完全合法的,但我得到的错误case expressions must be constant expressions Eclipse中的case expressions must be constant expressions 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. 我可以使用一组简单的if语句解决这个问题,但我想知道这个错误的原因以及如果允许的话,事情可能会向南发展。

NOTE: I cannot change the structure of Friends 注意:我无法更改Friends的结构

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 Friends instance, 根据您的评论,您需要编写一个静态方法来获取正确的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. valueOf(String)将匹配枚举字段的名称。 So "Ian", "Sarah" or "Peter". 所以“伊恩”,“莎拉”或“彼得”。

This seems perfectly legal to me 这对我来说似乎完全合法

Well it's not - a method call is never a constant expression. 嗯,不是 - 方法调用永远不是一个常量表达式。 See JLS 15.28 for what constitutes a constant expression. 有关常量表达式的构成,请参见JLS 15.28 And a case value always has to be a constant expression. 案例值总是必须是一个常量表达式。

The simplest fix would be to have a Friend.fromFullName static method, which perhaps looked the Friend up in a HashMap<String, Friend> . 最简单的解决方法是拥有一个Friend.fromFullName静态方法,它可能在HashMap<String, Friend>看起来像Friend (You don't have to have that method in Friend of course... it's just that would be the most conventional place.) Then you could switch over the enum rather than the name. (您不必有这种方法在Friend ,当然......它只是将是最传统的地方。)然后,你可以在枚举切换而不是名称。

As a side note, your enum name should be in the singular and with ALL_CAPS members, so Friend.PETER etc. 作为旁注,你的枚举名称应该是单数的,并且有ALL_CAPS成员,所以Friend.PETER等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM