以下是Sun 的 Java 教程的摘录:
开关适用于
byte
、short
、char
和int
原始数据类型。它也适用于枚举类型(在类和继承中讨论)和一些“包装”某些原始类型的特殊类:、、、和Character
(在简单数据对象中讨论)。Byte
Short
Integer
long
不允许使用原始数据类型必须有充分的理由。有人知道这是什么吗?
以下是Sun 的 Java 教程的摘录:
开关适用于
byte
、short
、char
和int
原始数据类型。它也适用于枚举类型(在类和继承中讨论)和一些“包装”某些原始类型的特殊类:、、、和Character
(在简单数据对象中讨论)。Byte
Short
Integer
long
不允许使用原始数据类型必须有充分的理由。有人知道这是什么吗?
我认为在某种程度上,这可能是基于 switch 的典型使用的任意决定。
switch 本质上可以通过两种方式实现(或原则上是组合方式):对于少数情况,或者值分布广泛的情况,switch 本质上相当于临时变量上的一系列 ifs(被打开的值只能被评估一次)。对于值或多或少连续的中等数量的情况,使用切换表(Java 中的 TABLESWITCH 指令),从而有效地在表中查找要跳转到的位置。
这些方法中的任何一种原则上都可以使用长值而不是整数。但我认为这可能只是平衡指令集和编译器的复杂性与实际需要的实际决定:您真正需要切换 long 的情况非常罕见,以至于不得不重写为一系列 IF 语句,或以其他方式工作(如果所讨论的 long 值非常接近,您可以在 Java 代码中切换 int 结果减去最小值)。
因为他们没有在字节码中实现必要的指令,而且你真的不想写那么多案例,不管你的代码有多“生产就绪”......
[编辑:摘自对此答案的评论,并在背景中添加了一些内容]
确切地说,2³² 是很多情况,任何具有足够长的方法来容纳超过 2³² 的程序都将是非常可怕的!任何语言。(我所知道的任何语言的任何代码中最长的函数都略高于 6k SLOC——是的,它很大switch
——而且真的难以管理。)如果你真的坚持long
只有一个int
或更少的地方,那么你有两个真正的选择。
使用散列函数主题的一些变体long
将int
. 最简单的一种,仅在您输入错误时使用,就是强制转换!更有用的是这样做:
(int) ((x&0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF))
在打开结果之前。您还必须弄清楚如何转换您正在测试的案例。但实际上,这仍然很可怕,因为它没有解决很多案例的真正问题。
如果您正在处理大量案例,一个更好的解决方案是将您的设计更改为使用 aMap<Long,Runnable>
或类似的东西,以便您查找如何调度特定值。这允许您将案例分成多个文件,当案例数量变大时,这更容易管理,尽管组织所涉及的实现类的主机的注册确实变得更加复杂(注释可能会帮助您自动生成注册码)。
FWIW,我在很多年前就这样做了(我们在项目的一部分中切换到新发布的 J2SE 1.2),当时我构建了一个自定义字节码引擎来模拟大规模并行硬件(不,重用 JVM 是不合适的,因为从根本上涉及不同的价值和执行模型),并且相对于switch
C 版本的代码使用的代码,它极大地简化了代码。
重申一下重要信息,想要switch
on along
表示您的程序中的类型错误,或者您正在构建一个包含大量变化的系统,您应该使用类。是时候重新考虑这两种情况了。
因为查找表索引必须是32位。
A long, in 32bit architectures, is represented by two words. Now, imagine what could happen if due to insufficient synchronization, the execution of the switch statement observes a long with its high 32 bits from one write, and the 32 low ones from another! It could try to go to ....who knows where! Basically somewhere at random. Even if both writes represented valid cases for the switch statement, their funny combination would probably lead neither to the first nor to the second -- or extremely worse, it could lead to another valid, but unrelated case!
At least with an int (or lesser types), no matter how badly you mess up, the switch statement will at least read a value that someone actually wrote, instead of a value "out of thin air".
Of course, I don't know the actual reason (it's been more than 15 years, I haven't been paying attention that long!), but if you realize how unsafe and unpredictable such a construct could be, you'll agree that this is a definitely very good reason not to ever have a switch on longs (and as long -pun intended- there will be 32bit machines, this reason will remain valid).