已经有两个“主观性强”的关闭投票了。确实,没有人能够在这里给出一个确定的答案,当试图争论一群工程师25年前所做的决定时,可能会涉及到一些敷衍塞责的行为。但我会试着回答这个问题...
首先,我认为这个问题是有道理的:int类型是Java语言中最“突出”的类型(最后但并非最不重要的原因是它在数组索引中的作用)。这与它在Java虚拟机中的特殊角色相呼应,在该角色中,所有存在于语言中的(更小的)整数类型,如byte或short,在所有计算中都被有效地转换为int。或者,如
Java虚拟机规范第2.11.7节中所述:
由于它强调int比较,Java虚拟机为类型int提供了丰富的条件分支指令。
现在合理地问,为什么这个“丰富的补充”似乎排除了对所有其他类型同等存在的指令的使用。
没有icmp指令的主要原因可能是它既不必要也没有好处。
使用它来比较Integer#compare(int, int)的建议应用案例几乎不能算作一个论据:即使存在icmp,这样一种方法的实现也不会是
return icmp, arg0, arg1;
将方法转换为字节码可以相当复杂,而且考虑到Java语言本身的可能性,这样的方法必须等效地实现。
if (x > y) return 1;
if (x < y) return -1;
return 0;
很显然,这可以被翻译成一系列现有的if_icmp<?>
指令。
在此需要记住的是这些比较指令的主要目的是分支:它们会导致跳转到不同的位置。它们并不用于将一个值推送到堆栈上,然后“用作方法的返回值”。在这里,谈论语言和谈论虚拟机是两个完全不同的事情。
人们也可以反过来问:为什么long
、float
和double
都有lcmp
、fcmp_
和dcmp_
指令呢?
这里,答案明确得多:为long
、float
和double
提供整套的eq
、ne
、lt
、le
、gt
和ge
比较指令将意味着增加18个附加指令(对于浮点类型的NaN
处理可能还更多)。考虑到单字节最多只能使用256个指令,这是很多的。
通过为这些类型提供lcmp
、fcmp_
和dcmp_
指令,可以使用剩余的指令来模拟所有其他可能的比较情况。但再次强调,这些主要用于分支,因此并不需要icmp
指令,因为对于int
,所有必要的分支指令(“跳转条件”)已经可用。
Long.compare
并没有直接使用 lcmp;只是 long 类型的 <、> 等操作是基于 lcmp 实现的。 - Louis Wasserman