Why can't I use switch statement on a String?

2018-12-31 01:10发布

Is this functionality going to be put into a later Java version?

Can someone explain why I can't do this, as in, the technical way Java's switch statement works?

14条回答
像晚风撩人
2楼-- · 2018-12-31 01:48

Not very pretty, but here is another way for Java 6 and bellow:

String runFct = 
        queryType.equals("eq") ? "method1":
        queryType.equals("L_L")? "method2":
        queryType.equals("L_R")? "method3":
        queryType.equals("L_LR")? "method4":
            "method5";
Method m = this.getClass().getMethod(runFct);
m.invoke(this);
查看更多
其实,你不懂
3楼-- · 2018-12-31 01:55

For years we've been using a(n open source) preprocessor for this.

//#switch(target)
case "foo": code;
//#end

Preprocessed files are named Foo.jpp and get processed into Foo.java with an ant script.

Advantage is it is processed into Java that runs on 1.0 (although typically we only supported back to 1.4). Also it was far easier to do this (lots of string switches) compared to fudging it with enums or other workarounds - code was a lot easier to read, maintain, and understand. IIRC (can't provide statistics or technical reasoning at this point) it was also faster than the natural Java equivalents.

Disadvantages are you aren't editing Java so it's a bit more workflow (edit, process, compile/test) plus an IDE will link back to the Java which is a little convoluted (the switch becomes a series of if/else logic steps) and the switch case order is not maintained.

I wouldn't recommend it for 1.7+ but it's useful if you want to program Java that targets earlier JVMs (since Joe public rarely has the latest installed).

You can get it from SVN or browse the code online. You'll need EBuild to build it as-is.

查看更多
浮光初槿花落
4楼-- · 2018-12-31 01:59

James Curran succinctly says: "Switches based on integers can be optimized to very efficent code. Switches based on other data type can only be compiled to a series of if() statements. For that reason C & C++ only allow switches on integer types, since it was pointless with other types."

My opinion, and it's only that, is that as soon as you start switching on non-primitives you need to start thinking about "equals" versus "==". Firstly comparing two strings can be a fairly lengthy procedure, adding to the performance problems that are mentioned above. Secondly if there is switching on strings there will be demand for switching on strings ignoring case, switching on strings considering/ignoring locale,switching on strings based on regex.... I would approve of a decision that saved a lot of time for the language developers at the cost of a small amount of time for programmers.

查看更多
萌妹纸的霸气范
5楼-- · 2018-12-31 02:00
public class StringSwitchCase { 

    public static void main(String args[]) {

        visitIsland("Santorini"); 
        visitIsland("Crete"); 
        visitIsland("Paros"); 

    } 

    public static void visitIsland(String island) {
         switch(island) {
          case "Corfu": 
               System.out.println("User wants to visit Corfu");
               break; 
          case "Crete": 
               System.out.println("User wants to visit Crete");
               break; 
          case "Santorini": 
               System.out.println("User wants to visit Santorini");
               break; 
          case "Mykonos": 
               System.out.println("User wants to visit Mykonos");
               break; 
         default: 
               System.out.println("Unknown Island");
               break; 
         } 
    } 

} 
查看更多
几人难应
6楼-- · 2018-12-31 02:01

When you use intellij also look at:

File -> Project Structure -> Project

File -> Project Structure -> Modules

When you have multiple modules make sure you set the correct language level in the module tab.

查看更多
几人难应
7楼-- · 2018-12-31 02:03

The following is a complete example based on JeeBee's post, using java enum's instead of using a custom method.

Note that in Java SE 7 and later you can use a String object in the switch statement's expression instead.

public class Main {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {

      String current = args[0];
      Days currentDay = Days.valueOf(current.toUpperCase());

      switch (currentDay) {
          case MONDAY:
          case TUESDAY:
          case WEDNESDAY:
              System.out.println("boring");
              break;
          case THURSDAY:
              System.out.println("getting better");
          case FRIDAY:
          case SATURDAY:
          case SUNDAY:
              System.out.println("much better");
              break;

      }
  }

  public enum Days {

    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
  }
}
查看更多
登录 后发表回答