【发布时间】:2008-11-21 08:56:06
【问题描述】:
有谁知道为什么 Java 不允许你打开大于整数的数字?这背后有什么技术原因吗?
【问题讨论】:
标签: java
有谁知道为什么 Java 不允许你打开大于整数的数字?这背后有什么技术原因吗?
【问题讨论】:
标签: java
正如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 语句,而不是按顺序逐一测试。
【讨论】:
Scala 是一种建立在 JVM 之上的语言,它允许您定义自己的案例类,您可以在 switch 语句中使用这些案例类。因此,在 switch 语句中使用 longs 或 doubles 或 Strings 肯定是可能的。
但我不知道它有多复杂和有多有效。对于简单类型,编译器只需计算偏移量以在表上跳转。更复杂的类型绝对不是这种情况。
我想答案与设计 java 的时间和设计者试图实现的目标有关。 Java 最初的目标是设计一种“更好的 C++”,可在许多环境中移植。我可以理解为什么复杂类型的开关不适合它。
【讨论】:
我的猜测是,long 被丢弃为有效的 switch 表达式类型,因为/与对 long 变量 may not be atomic 的操作有关。
【讨论】:
如果您发现本机 java 开关结构限制太多,请看一下 lambdaj Switcher,它允许通过将任何对象与一些 hamcrest 匹配器匹配来以声明方式打开任何对象。
【讨论】:
也许是因为在 switch 中有超过整数最大情况的编程真的很糟糕?
如果要切换长变量,只需将它们投影到整数空间即可。
【讨论】: