Java:在子类下使用带有枚举的switch语句

Pop*_*oko 239 java enums switch-statement

首先,我将说明我对C#中的枚举更加熟悉,看起来java中的枚举非常混乱.

正如您所看到的,我正在尝试在下一个示例中使用switch语句@enums,但无论我在做什么,我总是会收到错误.

我收到的错误是:

SomeClass.AnotherClass.MyEnum.VALUE_A必须使用不合格的枚举常量替换合格的案例标签VALUE_A

事情是我非常理解错误,但我不能只编写VALUE_A,因为枚举位于另一个子类中.有没有办法解决这个问题?为什么它会在Java中发生?

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        MyEnum enumExample //...

        switch (enumExample) {
            case AnotherClass.MyEnum.VALUE_A: { <-- error on this line
                //..
                break;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

dar*_*man 524

把它改成这个:

switch (enumExample) {
    case VALUE_A: {
        //..
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

线索出现错误.您不需要case使用枚举类型限定标签,只需使用其值.

  • 好吧,我觉得这么愚蠢:-(你是完全正确的,我确信我尝试了这个确切的行,并得到了一个错误,所以我搬到了资格案件,但你的建议工作. (20认同)
  • @milkplusvellocet,我知道这个帖子已经很老了,但我很好奇为什么Java不允许在switch语句中使用**合格的case标签**? (11认同)
  • 顺便说一下,我认为你会发现,一旦你开始更多地使用它们,Java中的枚举就非常有用了,我不会说它们一团糟啊:) (4认同)
  • 早在 2015 年就已经对此答案进行了投票..我们再次开始:D 仍然不明白为什么限定名称是编译器错误。就像,如果它丑陋且多余,那就这样吧,这是我的责任。我的IDE可以告诉我这是不必要的,但是编译会崩溃吗?我不知道......至少对我来说似乎很奇怪,因此不直观。 (3认同)
  • @ cRane01不确定,但它使语法更清晰.在每种情况下指定类型将是完全多余的 (2认同)
  • @HelloGoodbye否.switch语句的变量定义case语句的类型,因此它只能是一个枚举. (2认同)

Kru*_*Kru 31

Java自动推断元素的类型case,因此标签必须是不合格的.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么_它不合格? (13认同)
  • 如果你有资格,那么你可能会使用"MyEnum"之外的其他东西,这是没有意义的. (11认同)
  • @Kru,但我 ** 可以** 对非枚举类型的 case 表达式使用其他语法。例如`static final int MY_CONST = 7; ……; switch(intVariable) {case MY_CONST: ...;}` 而不是 `case 7`。因此,对枚举的这种限制使 ** 没有** 意义(我不仅可以使用主文字,还可以为整数“switch”表达式使用手动定义的常量,但我不能使用手动定义的常量,而只能使用主名称)枚举)。 (2认同)

Aka*_*ppa 24

错误的:

case AnotherClass.MyEnum.VALUE_A
Run Code Online (Sandbox Code Playgroud)

对:

case VALUE_A:
Run Code Online (Sandbox Code Playgroud)

  • 我对你的投了赞成票,因为它更清楚地说明了问题是什么。 (7认同)

hba*_*ara 6

Java 14开始,可以使用 switch 表达式。

对于这篇文章

public enum MyEnum {
    VALUE_A, VALUE_B;
}
Run Code Online (Sandbox Code Playgroud)
public void someMethod() { 
    MyEnum enumExample //...

    switch (enumExample) {
        case VALUE_A -> {
            // logic
        }
        case VALUE_B -> {
            // logic
        }   
    }
}
Run Code Online (Sandbox Code Playgroud)

开关表达式

与所有表达式一样,switch 表达式的计算结果为单个值,并且可以在语句中使用。它们可能包含“case L ->”标签,无需使用break语句来防止失败。您可以使用yield 语句来指定switch 表达式的值。

public enum Month {
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC;
}
Run Code Online (Sandbox Code Playgroud)

示例1:返回值。

public static int getNoOfDaysInAMonth(Month month, boolean isLeapYear) {
    return switch(month) {
        case APR, JUN, SEP, NOV -> 30;
        case FEB -> (isLeapYear)? 29: 28;
        case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
    };
}
Run Code Online (Sandbox Code Playgroud)

示例 2:不返回值。

public static void printNoOfDaysInAMonth(Month month, boolean isLeapYear) {
    switch(month) {
        case APR, JUN, SEP, NOV -> {
            System.out.println("30 days");
        }
        case FEB -> {
            System.out.println(((isLeapYear)? 29: 28) + " days");
        }
        case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> {
            System.out.println("31 days");
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

参考

切换表达式


小智 5

这应该做:

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        AnotherClass.MyEnum enumExample = AnotherClass.MyEnum.VALUE_A; //...

        switch (enumExample) {
            case VALUE_A: { //<-- error on this line
            //..
            break;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)