【问题标题】:Java and switch caseJava 和 switch 案例
【发布时间】:2008-11-21 08:56:06
【问题描述】:

有谁知道为什么 Java 不允许你打开大于整数的数字?这背后有什么技术原因吗?

【问题讨论】:

    标签: java


    【解决方案1】:

    正如here 所说,switch 可用于 byte、short、char 和 int 原始数据类型。它还适用于枚举类型和一些“包装”某些基本类型的特殊类:Character、Byte、Short 和 Integer。

    Java switch 语句被编译成JVM bytecode tableswitch or lookupswitch。这两种字节码都要求大小写值是唯一的、32 位整数、编译时常量。

    tableswitch 和 lookupswitch 指令都包含一个默认分支偏移量和一组可变长度的 case 值/分支偏移量对。
    两条指令都从堆栈中弹出键(括号中紧跟 switch 关键字的表达式的值)。
    将键与所有 case 值进行比较:

    • 如果找到匹配项,则采用与案例值关联的分支偏移量。
    • 如果未找到匹配项,则采用默认分支偏移量。

    尽管上面代表了实现细节,但我相信 用于 switch 的类型是与控制流的有效字节码兼容的类型,因此它可能是一个重要的部分选择。

    正如Java Bug中所说:

    我想你可以允许 Java switch 语句包含其他类型的值,并将使用其中一种值的 switch 语句编译到其他字节码中,例如 ifs 和 goto 序列。但随后我们必须仔细检查所有 switch 语句,以确定它是否会被编译成快速 switch 字节码或慢速 if-else 序列。

    正如其他Java bug所说的

    'switch' 语句可以使用函数表分派和/或二叉树搜索来匹配 case 语句,而不是按顺序逐一测试。

    【讨论】:

    • 这是实现细节。不是这种选择的实际原因。
    【解决方案2】:

    Scala 是一种建立在 JVM 之上的语言,它允许您定义自己的案例类,您可以在 switch 语句中使用这些案例类。因此,在 switch 语句中使用 longs 或 doubles 或 Strings 肯定是可能的。

    但我不知道它有多复杂和有多有效。对于简单类型,编译器只需计算偏移量以在表上跳转。更复杂的类型绝对不是这种情况。

    我想答案与设计 java 的时间和设计者试图实现的目标有关。 Java 最初的目标是设计一种“更好的 C++”,可在许多环境中移植。我可以理解为什么复杂类型的开关不适合它。

    【讨论】:

      【解决方案3】:

      我的猜测是,long 被丢弃为有效的 switch 表达式类型,因为/与对 long 变量 may not be atomic 的操作有关。

      【讨论】:

      • 我认为这不是原因。如果是这样,那么 if else 也应该受到限制,对吗?我认为它与 VonC 指出的处理器的寻址模式有关(因为 switch 没有像 else 结构那样编译成相同的字节码)。
      【解决方案4】:

      如果您发现本机 java 开关结构限制太多,请看一下 lambdaj Switcher,它允许通过将任何对象与一些 hamcrest 匹配器匹配来以声明方式打开任何对象。

      【讨论】:

        【解决方案5】:

        也许是因为在 switch 中有超过整数最大情况的编程真的很糟糕?

        如果要切换长变量,只需将它们投影到整数空间即可。

        【讨论】:

        • 请不要对这个答案投反对票!它解释了为什么 Java 语言设计者认为将 switch 语句限制为 32 位类型是合理的。
        • 这不是理由,是猜测。将 long 投影到整数空间也违背了使用 long 的目的。
        • 这将是一个非常愚蠢的理由,想象一下你需要切换一些长比特序列。
        猜你喜欢
        • 2013-12-08
        • 1970-01-01
        • 2010-10-12
        • 1970-01-01
        • 1970-01-01
        • 2016-01-17
        • 1970-01-01
        • 2010-10-23
        • 1970-01-01
        相关资源
        最近更新 更多