考虑以下代码:
public class ShortDivision {
public static void main(String[] args) {
short i = 2;
short j = 1;
short k = i/j;
}
}
编译它会产生错误
ShortDivision.java:5: possible loss of precision
found : int
required: short
short k = i/j;
因为表达式i / j的类型显然是int,因此必须转换为short。
为什么i/j
的类型不短?
答案 0 :(得分:18)
来自Java spec:
5.6.2二进制数字促销
当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示数值类型的值,以下规则按顺序应用,使用扩展转换(第5.1.2节)根据需要转换操作数:
如果任一操作数的类型为double,则另一个操作数转换为double。
否则,如果任一操作数的类型为float,则另一个操作数转换为float。
否则,如果任一操作数的类型为long,则另一个操作数转换为long。
否则,两个操作数都将转换为int类型。
对于二进制操作,小整数类型被提升为int
,操作结果为int
。
编辑:为什么会这样?简短的回答是Java从C复制了这种行为。更长的答案可能与所有现代机器至少进行32位本机计算这一事实有关,而且某些机器实际上可能更难做8位和16位操作。
答案 1 :(得分:2)
关于动机:让我们想象一下这种行为的替代方案,看看为什么它们不起作用:
备选方案1:结果应始终与输入相同。
添加int和short的结果应该是什么?
两个短裤相乘的结果应该是什么?结果通常适合int,但因为我们截断为short,所以大多数乘法都会无声地失败。之后施放到int将无济于事。
备选方案2:结果应始终是可以代表所有可能输出的最小类型。
如果返回类型很短,则答案并不总是可以表示为短。
空头可以持有-32,768到32,767的值。然后这个结果会导致溢出:
short result = -32768 / -1; // 32768: not a short
所以你的问题变成了:为什么添加两个整数不会返回多长?两个整数应该乘以什么?好久不过?一个BigNumber来覆盖整数最小值的情况?
备选方案3:选择大多数人可能最需要的东西
所以结果应该是:
如果没有基本逻辑,记住所有特殊情况都会很困难。简单地说:整数运算的结果总是一个int。
答案 2 :(得分:0)
它只是一种设计选择,与C / C ++保持一致,在设计Java时它们是主导语言。
例如,可以实现i * j,以便从byte =>提升类型。 short,short => int,和int =>很长,这样可以避免溢出,但事实并非如此。 (它在某些语言中有用)如果需要当前的行为,可以使用Casting,但是一些位的丢失将是明确的。
类似地,可以从byte / short =>提示i / j; float或int / long =>双