为什么你的switch语句数据类型不能长,Java?

Fos*_*tah 74 java language-design switch-statement long-integer

以下是Sun Java教程的摘录:

一种开关用的工作原理byte,short,char,和int原始数据类型.它还与枚举类型(在类和继承讨论)和少数特殊类作品是"包装"某些基本类型:Character,Byte,Short,和Integer(在简单的数据对象讨论).

必须有一个很好的理由为什么long不允许原始数据类型.有人知道这是什么吗?

Nei*_*fey 47

我认为在某种程度上,这可能是基于典型切换使用的任意决定.

交换机基本上可以通过两种方式实现(或者原则上是组合):对于少数情况,或者其值大范围分散的情况,交换机基本上等同于临时变量上的一系列ifs(打开的值必须只评估一次).对于或多或少连续值的中等数量的情况,使用切换表(Java中的TABLESWITCH指令),从而有效地在表中查找要跳转到的位置.

这些方法中的任何一个原则上都可以使用长值而不是整数.但是我认为将指令集和编译器的复杂性与实际需求进行平衡可能只是一个实际的决定:你需要切换很长时间的情况很少见,因此必须重新编写为一系列的IF语句,或以其他方式工作(如果有问题的长值靠得很近,你可以在你的Java代码中切换int减去最低值的结果).

  • 最愚蠢的设计决定.我有一长串,这是一堆旗帜,我必须携带如果......其他如果......其他......完全荒谬. (12认同)
  • Dimitris,我的推理并非基于对线程安全的中间理解,只是因为我认为你提出的线程安全论点不成立. (3认同)
  • 我同意w/@ m0skit0.就我而言,其他人编写了一个使用long作为常量的API,因为这是他们在数据库中存储的内容.现在我不能使用开关/箱子,因为别人的决定不好. (2认同)
  • 我不是说这是“世界末日”。而且,是的,有很多方法可以解决,但它们看起来都像黑客。我的观点是,作为开发人员,我们应该始终考虑过去我们认为人们将如何使用我们构建的东西。在这种情况下,有人基于“谁会诚实地拥有 2^64 个案例”的最初想法,决定不允许长时间切换/案例。也许这是一种过度简化。也许还有一些其他原因导致无法切换多头,因为我们也不是很了解。对我来说,不支持它似乎很奇怪。 (2认同)

Don*_*ows 19

因为他们没有在字节码中实现必要的指令,你真的不想写那么多的情况,无论你的代码如何"生产就绪"......

[编辑:摘自对此答案的评论,并在背景上添加一些内容]

确切地说,2,32是很多情况下,任何方法都有足够长的时间来容纳更多的东西,这将是非常可怕的!用任何语言.(我知道的任何语言的任何代码最长的功能是在6K小SLOC -是的,这是一个很大的switch-它真的无法控制的)如果你真的坚持与具有正long,你应该只有一个int或更少,那么你有两个真正的选择.

  1. 在哈希函数的主题上使用一些变体来压缩long成一个int.最简单的一个,只有当你输入错误时才使用,就是施展!更有用的是这样做:

    (int) ((x&0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF))
    
    Run Code Online (Sandbox Code Playgroud)

    在打开结果之前.你必须弄清楚如何改变你正在测试的案例.但实际上,这仍然很可怕,因为它没有解决许多案件的真正问题.

  2. 如果您正在处理大量案例,那么更好的解决方案是将您的设计更改为使用Map<Long,Runnable>类似的东西,以便您查找如何分配特定值.这允许您将案例分成多个文件,这在案例数量变大时更容易管理,尽管组织所涉及的实现类主机的注册变得更加复杂(注释可能有助于您自动构建注册码).

    FWIW,我做了这许多年以前(我们通过项目切换到新推出的J2SE 1.2的一部分的方式)建立一个自定义的字节码引擎时,用于模拟大规模并行硬件(无,重复使用JVM不会有合适的,由于根本所涉及的不同的值和执行模型)并且它极大地简化了相对于代码switch的C版本所使用的大的代码.

要重申带回家的消息,想要switch在a long上表明你的程序中的类型错误,或者你正在构建一个涉及很多变化的系统,你应该使用类.在任何一种情况下重新考虑的时间.

  • @Lord Torgamus:大概是因为它很傻.想一想:为什么有人,*任何人*,在'switch`中拥有超过2**32个武器的代码?想要选择那么多元素的有限集合只是指出程序的基本设计中的错误.人们要求它只是表明**他们的设计错了**. (3认同)
  • _“要重申该提示,想要长时间打开表示您的程序中的类型错误” _-不,不是!具有`long`并不意味着您将检查所有可能性,就像拥有`int`或`String`也不意味着那样。这意味着您拥有的值(可能很少)具有较大的_range_。您可能正在检查一些简单的案例,其余的都属于“ default”。必须进行轮班和强制转换意味着您将有丢失数据的风险。归根结底,这是一个糟糕的Java设计决策,而不是用户问题。 (3认同)
  • @DonalFellows,另一个案例是在Android中使用ListView的.虽然listViews可以有很长的行数,但我特别需要4个.这是我的一个'long`递给我的情况,表明正在对哪一行进行操作,我需要根据哪个行做不同的事情.这是一排.我想我可以转换为int,但是如果我只能对变量进行"切换",它会让我的生活更轻松.实际上,我只是使用一串`if`和`else if`代替. (2认同)

JRL*_*JRL 6

因为查找表索引必须是32位的。

  • 如果是这样,他们永远无法实现字符串的 switch(正如他们目前计划的那样)。 (11认同)
  • 但是又一次`switch` 不一定需要用查找表来实现。 (3认同)