首先,我要声明我对 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;
}
}
}
}
Enum
的窍门,它们就会非常方便使用——一点也不混乱。它们比在其他平台上看到的简单枚举(仅仅是一个标记的整数值)更加灵活和实用。参见Oracle Tutorial。发现优化的 Set
/Map
实现:EnumSet
& EnumMap
。
将其更改为:
switch (enumExample) {
case VALUE_A: {
//..
break;
}
}
线索在错误中。您无需使用枚举类型限定 case
标签,只需使用其值即可。
错误的:
case AnotherClass.MyEnum.VALUE_A
正确的:
case VALUE_A:
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
}
MyEnum
以外的其他内容,这没有意义。
static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}
而不是 case 7
。因此,对枚举的这种限制使 no 有意义(我不仅可以使用主要文字,还可以为整数 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;
}
}
}
}
从 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:不返回值。
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");
}
};
}
参考
这就是我使用它的方式。它工作得非常好——
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;
}
}
}
以这种方式编写 someMethod()
:
public void someMethod() {
SomeClass.AnotherClass.MyEnum enumExample = SomeClass.AnotherClass.MyEnum.VALUE_A;
switch (enumExample) {
case VALUE_A:
break;
}
}
在 switch 语句中,您必须仅使用常量名称。