为什么我不能打开一个字符串?

为什么我不能打开一个String

这个功能是否会被放到更高版本的Java中?

有人可以解释为什么我不能这样做,因为Java的switch语句的技术方式有效吗?


在Java SE 7中已经实现了使用String情况的开关语句,至少在第一次请求后16年。 没有提供明确的延迟原因,但可能与性能有关。

在JDK 7中实现

这个特性现在已经在javac中用“脱糖”过程实现了; 在声明的case在编译时扩展为一个模式之后的更复杂的代码时,使用String常量的干净的高级语法。 生成的代码使用始终存在的JVM指令。

在编译期间,具有String情况的switch将被转换为两个开关。 第一个将每个字符串映射到一个唯一的整数 - 它在原始开关中的位置。 这是通过首先打开标签的哈希码完成的。 相应的情况是一个if语句,用于测试字符串相等性; 如果散列上存在冲突,则测试是级联的if-else-if 。 第二个开关反映原始源代码中的内容,但将外壳标签替换为对应的位置。 这两步流程可以轻松保留原始交换机的流量控制。

JVM中的开关

有关switch更多技术深度,可以参考描述switch语句编译的JVM规范。 简而言之,有两种不同的JVM指令可用于开关,具体取决于案例使用的常量的稀疏性。 两者都依赖于为每个案例使用整数常量来有效执行。

如果常量是密集的,则它们被用作索引(在减去最低值之后)到指令指针表( tableswitch指令)中。

如果常量稀疏,则执行正确大小写的二进制搜索 - lookupswitch指令。

在删除String对象的switch时,可能会使用这两条指令。 lookupswitch适用于第一次开启散列码以查找案件的原始位置。 由此产生的序数是天生适合tableswitch

两条指令都要求在编译时分配给每个case的整型常量进行排序。 在运行时,而O(1)性能tableswitch普遍显得比更好的O(log(n))性能lookupswitch ,它需要一些分析,以确定该表是否足够密集证明时空权衡。 Bill Venners撰写了一篇很好的文章,详细介绍了这一点,并详细介绍了其他Java流程控制指令。

在JDK 7之前

在JDK 7之前, enum可以近似基于String的开关。 这使用编译器在每个enum类型上生成的静态valueOf方法。 例如:

Pill p = Pill.valueOf(str);
switch(p) {
  case RED:  pop();  break;
  case BLUE: push(); break;
}

如果你的代码中有一个可以打开字符串的地方,那么重构字符串可能会更好,因为它是可以打开的可能值的枚举。 当然,你可以将枚举中的字符串的潜在值限制在枚举中,这些值可能是需要的,也可能不需要。

当然你的枚举可以有'other'和fromString(String)方法的条目,那么你可以有

ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
   case MILK: lap(); break;
   case WATER: sip(); break;
   case BEER: quaff(); break;
   case OTHER: 
   default: dance(); break;
}

以下是基于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
  }
}
链接地址: http://www.djcxy.com/p/2427.html

上一篇: Why can't I switch on a String?

下一篇: Variable declaration in a C# switch statement