2011-06-17 49 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()。 –