int类型的基本算术运算 - Java

13

最近我注意到了Java在基本算术运算上的一些特殊情况。以下是代码:

byte a = 3;
byte b = 4;
byte c = a * b;

我遇到了一个 "type mismatch" 编译错误...

在Java中,基本算术运算(+, -, *, /)只针对于原始数据类型如int和更高级别的类型(如longdouble等)进行操作,而对于byteshort 等类型进行算术运算时会先转换为int然后再进行计算吗?


好问题。老实说,我不知道答案,但是找到了这个链接。http://mindprod.com/jgloss/multiplication.html - Zutty
2个回答

17

bytecharshort 的操作会被扩展为 int,除非编译器能够确定值的范围。

final byte a = 3, b = 4;
byte c = a * b; // compiles

final byte a = 3, b = 40;
byte c = a * b; // compiles

final int a = 3, b = 4;
byte c = a * b; // compiles !!

但是
byte a = 3, b = 4;
byte c = a * b; // doesn't compile as the result of this will be `int` at runtime.

final byte a = 30, b = 40;
byte c = a * b; // doesn't compile as the value is too large, will be an `int`

顺便说一句,尽管会导致溢出,但这段代码仍然可以编译。:]
final int a = 300000, b = 400000;
int c = a * b; // compiles but overflows, is not made a `long`

1
哎呀,我不知道在这里使用 final 会有这么大的区别。但是无论如何,看起来很奇怪,因为即使在第二个例子中,ab 仍然被声明为字节... - fge
3
除非编译器能确定值在范围内,否则它是一个处于范围内的常量表达式 - assylias

7
整数运算的结果是 int 或者 long。这在JLS中有明确说明: 4.2.2. 整数运算 数字运算符,其结果为类型 intlong
  • 一元加减运算符+和-(§15.15.3、§15.15.4)
  • 乘法运算符*、/和%(§15.17)
  • 加法和减法运算符+和-(§15.18)
  • ...
此外,还有5.6.2. 二进制数值提升 当运算符对一对操作数应用二进制数值提升时,每个操作数都必须表示可转换为数值类型的值,按照以下规则依次应用:
  • 根据以下规则指定的方式,将扩展原始转换(§5.1.2)应用于转换一个或两个操作数:
  • 如果任何一个操作数是 double 类型,则另一个操作数被转换为 double 类型。
  • 否则,如果任何一个操作数是 float 类型,则另一个操作数被转换为 float 类型。
  • 否则,如果任何一个操作数是 long 类型,则另一个操作数被转换为 long 类型。
  • 否则,两个操作数都被转换为 int 类型。
二进制数值提升会在以下运算符的操作数上执行:
  • 乘法运算符*、/和%(§15.17)
  • 数字类型的加法和减法运算符+和-(§15.18.2)
  • 数字比较运算符<、<=、>和>=(§15.20.1)
  • 数字等式运算符==和!=(§15.21.1)
  • 整数位运算符&、^和|(§15.22.1)
  • 在某些情况下,条件运算符?:(§15.25)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接