Java:在子类下使用枚举开关语句

首先我要声明的是,我更熟悉c#中的枚举,而java中的枚举似乎是相当混乱的。

正如你所看到的,我试图在下一个例子中使用一个switch语句@ enums,但无论我做什么,我总是得到一个错误。

我收到的错误是:

限定大小写标签SomeClass.AnotherClass.MyEnum.VALUE_A必须替换为限定enum常量VALUE_A

问题是我相当理解这个错误,但我不能只写VALUE_A,因为enum位于另一个子类中。有办法解决这个问题吗?为什么会发生在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;
}
}
}
}
208793 次浏览

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
}

改成这样:

switch (enumExample) {
case VALUE_A: {
//..
break;
}
}

线索就在错误中。你不需要用枚举类型限定case标签,只需要限定它的值。

这样写someMethod():

public void someMethod() {


SomeClass.AnotherClass.MyEnum enumExample = SomeClass.AnotherClass.MyEnum.VALUE_A;


switch (enumExample) {
case VALUE_A:
break;
}


}

在switch语句中,只能使用常量名。

这应该是:

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

这就是我使用它的方式。而且效果非常好

public enum Button {
REPORT_ISSUES(0),
CANCEL_ORDER(1),
RETURN_ORDER(2);


private int value;


Button(int value) {
this.value = value;
}


public int getValue() {
return value;
}
}

switch-case,如下所示

@Override
public void onClick(MyOrderDetailDelgate.Button button, int position) {
switch (button) {
case REPORT_ISSUES: {
break;
}
case CANCEL_ORDER: {
break;
}
case RETURN_ORDER: {
break;
}
}
}

错误的:

case AnotherClass.MyEnum.VALUE_A

正确的:

case VALUE_A:

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

对于这篇文章

public enum MyEnum {
VALUE_A, VALUE_B;
}
public void someMethod() {
MyEnum enumExample //...


switch (enumExample) {
case VALUE_A -> {
// logic
}
case VALUE_B -> {
// logic
}
}
}

转换表达式

像所有表达式一样,switch表达式计算为单个值,可以在语句中使用。它们可能包含“case L ->"不需要break语句来防止失败的标签。可以使用yield语句指定switch表达式的值。

public enum Month {
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC;
}

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

例2:Doesn't返回值。

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

参考

开关表达式 .