这个功能会被放到后面的Java版本中吗?

有人能解释一下为什么我不能这样做,比如,Java的switch语句工作的技术方式吗?


当前回答

这个回答很好地解释了技术细节。我只是想添加Java 12开关表达式,你可以用下面的语法做到这一点:

String translation(String cat_language) {
    return switch (cat_language) {
        case "miau miau" -> "I am to run";
        case "miauuuh" -> "I am to sleep";
        case "mi...au?" ->  "leave me alone";
        default ->  "eat";
    };
} 

其他回答

如果您没有使用JDK7或更高版本,可以使用hashCode()来模拟它。因为String.hashCode()通常为不同的字符串返回不同的值,并且总是为相同的字符串返回相同的值,所以它是相当可靠的(不同的字符串可以产生与评论中提到的@Lii相同的哈希代码,例如“FB”和“Ea”)。

所以,代码看起来是这样的:

String s = "<Your String>";

switch(s.hashCode()) {
case "Hello".hashCode(): break;
case "Goodbye".hashCode(): break;
}

这样,你在技术上开启了一个整型。

或者,你可以使用下面的代码:

public final class Switch<T> {
    private final HashMap<T, Runnable> cases = new HashMap<T, Runnable>(0);

    public void addCase(T object, Runnable action) {
        this.cases.put(object, action);
    }

    public void SWITCH(T object) {
        for (T t : this.cases.keySet()) {
            if (object.equals(t)) { // This means that the class works with any object!
                this.cases.get(t).run();
                break;
            }
        }
    }
}

这个回答很好地解释了技术细节。我只是想添加Java 12开关表达式,你可以用下面的语法做到这一点:

String translation(String cat_language) {
    return switch (cat_language) {
        case "miau miau" -> "I am to run";
        case "miauuuh" -> "I am to sleep";
        case "mi...au?" ->  "leave me alone";
        default ->  "eat";
    };
} 

下面是一个基于JeeBee的帖子的完整示例,使用java枚举而不是使用自定义方法。

注意,在Java SE 7及更高版本中,您可以在switch语句的表达式中使用String对象。

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

JDK-13中的JEP 354: Switch Expressions(预览)和JDK-14中的JEP 361: Switch Expressions(标准)将扩展Switch语句,使其可以用作表达式。

现在你可以:

直接从开关表达式中分配变量, 使用新形式的开关标签(case L ->): “case L ->”开关标签右侧的代码被限制为表达式、块或(为方便起见)throw语句。 每个大小写使用多个常量,用逗号分隔, 而且也没有更多的价值突破: 为了从switch表达式中产生一个值,用yield语句代替break with value语句。

所以答案(1,2)的演示可能是这样的:

  public static void main(String[] args) {
    switch (args[0]) {
      case "Monday", "Tuesday", "Wednesday" ->  System.out.println("boring");
      case "Thursday" -> System.out.println("getting better");
      case "Friday", "Saturday", "Sunday" -> System.out.println("much better");
    }

除了以上好的论点,我还要补充一点,今天很多人认为switch是Java过去过程化的过时残余(回到C时代)。

我不完全同意这个观点,我认为switch在某些情况下有它的用处,至少因为它的速度,无论如何,它比我在一些代码中看到的一系列级联数字要好…

但实际上,有必要考虑一下需要开关的情况,看看它是否不能被更面向对象的东西所取代。例如Java 1.5+中的枚举,也许是哈希表或其他集合(有时我后悔我们没有(匿名)函数作为第一类公民,就像Lua -没有开关-或JavaScript),甚至是多态性。