2011-06-17 162 views
104

可能重复:
Compilation error - switch with enum
Why do I get an Enum constant reference cannot be qualified in a case label?在Java中接通枚举

你为什么不能打开Java中的枚举?它看起来很简单,并且会为一些便利的代码做准备。这个问题也适用于String。您可以打开char,但不能打开String ...?

+11

向我们显示您的非工作枚举开关代码。 –

+1

为什么复制标志,看标题的精确程度,很容易找到新用户。 – Indigo

+0

你可以看一下这篇文章,看看它是如何完成的:http://www.tutorialspoint.com/javaexamples/method_enum.htm –

回答

209

你绝对可以打开枚举。从Java tutorials发布的示例。在枚举

public enum Day { 
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
} 

public class EnumTest { 
    Day day; 

    public EnumTest(Day day) { 
     this.day = day; 
    } 

    public void tellItLikeItIs() { 

     switch (day) { 
      case MONDAY: 
       System.out.println("Mondays are bad."); 
       break; 

      case FRIDAY: 
       System.out.println("Fridays are better."); 
       break; 

      case SATURDAY: 
      case SUNDAY: 
       System.out.println("Weekends are best."); 
       break; 

      default: 
       System.out.println("Midweek days are so-so."); 
       break; 
     } 
    } 
} 
+2

很好地回答这个问题的美丽例子。也就是说,我已经对Java进行了14年的编程,并且我不记得在生产代码中保留switch语句的情况。当一个switch语句比一系列if/else更好时,我总是在我的枚举上写一个实例方法,而不是按照Josh Bloch的建议。在我的''日''枚举中,我添加'公共字符串tellItLikeItis(){return“周中日子如此。”; }'然后'MONDAY','FRIDAY','SATURDAY'和'SUNDAY'覆盖该方法。 – GlenPeterson

+0

也就是说,我这样做是因为@GregMattes在第二个最流行的答案中提出的建议。 – GlenPeterson

+2

@GlenPeterson仅供参考如果您尝试优化速度,switch语句方法可能会更快,因为它只是字节码中的表查找。用你的方法,你必须把一个新的功能推到堆栈上。这是一个微型优化,但是如果速度是非常重要的,那么要牢记这一点。 – DIMMSum

22
  • 开关正常工作。

    enum MyEnum { CONST_ONE, CONST_TWO } 
    
    class Test { 
        public static void main(String[] args) { 
         MyEnum e = MyEnum.CONST_ONE; 
    
         switch (e) { 
          case CONST_ONE: System.out.println(1); break; 
          case CONST_TWO: System.out.println(2); break; 
         } 
        } 
    } 
    

    ideone.com demo

  • 开关的字符串在Java 7中

    上的所有新功能here阅读起来实施。

26

首先,您可以在Java中打开enum。我猜你打算说你不能,但你可以。 char s有一组值范围,所以很容易比较。字符串可以是任何东西。

A switch声明通常在底层编译中实现为jump table (branch table),这只有在有限的一组值的情况下才可能实现。 C#可以开启字符串,但会导致性能下降,因为无法使用跳转表。

Java 7及更高版本支持String switches具有相同的特征。

+7

建筑解释+1。 –

+0

有点代码示例会有帮助... –

10

您可能在开关盒中错误地使用了枚举。在通过CoolBeans与上面的例子比较..你可能会做以下几点:

switch(day) { 
    case Day.MONDAY: 
     // Something.. 
     break; 
    case Day.FRIDAY: 
     // Something friday 
     break; 
} 

确保您使用的实际枚举值,而不是EnumType.EnumValue

Eclipse中指出这一错误,但..

+0

+1但是,我发现当你分配时,你必须使用day = Day.Monday;否则,我得到'无法找到符号'编译错误。 – likejiujitsu

1

实际上,您可以在Java中使用带有Strings的switch语句......不幸的是,这是Java 7的一项新功能,大多数人还没有使用Java 7,因为它太新颖了。

64

实际上,你可以switchenum S,但你不能switchString s,至Java 7中你可能会考虑使用多态的方法调度与Java enum真是让人不是一个明确的switch。请注意,enum s是Java中的对象,而不仅仅是像C/C++中那样的int的符号。您可以使用enum类型的方法,然后不要编写switch,而只需调用该方法 - 一行代码:完成!

enum MyEnum { 
    SOME_ENUM_CONSTANT { 
     @Override 
     public void method() { 
      System.out.println("first enum constant behavior!"); 
     } 
    }, 
    ANOTHER_ENUM_CONSTANT { 
     @Override 
     public void method() { 
      System.out.println("second enum constant behavior!"); 
     } 
    }; // note the semi-colon after the final constant, not just a comma! 
    public abstract void method(); // could also be in an interface that MyEnum implements 
} 

void aMethodSomewhere(final MyEnum e) { 
    doSomeStuff(); 
    e.method(); // here is where the switch would be, now it's one line of code! 
    doSomeOtherStuff(); 
} 
+16

+1:从来没有见过这种方式。有趣。 – CoolBeans

+3

这种方法的好处之一是,根本不可能得到某些类型的错误。你不能错过开关盒(你可以错误地为一个特定的常量实现一个方法,但是没有任何东西会完全阻止这种情况发生!)。没有开关“默认”担心。此外,我看到了将枚举常量放入数组然后将其索引到数组中的代码 - 这会打开数组索引超出范围异常的可能性 - 只需使用枚举即可! Java枚举非常非常强大。尽可能了解他们对他们的有效使用方法。 –

+2

另请注意,如果您有几个枚举常量对于特定的方法都具有相同的行为(例如@CoolBeans每周的示例中周末日期具有相同的行为并且周二至周四的工作日也共享相同的行为),那么您可以简单地将这些共享代码收集在一个不被每个常量(最终保护)覆盖的枚举方法中,然后从适当的方法中调用该方法。因此,在我的示例中,我可以添加“final保护void commonMethod(){...}”,然后在每个常量中实现method()只需调用commonMethod()。 –