我对以下Java语句有疑问:
byte b = 10;
byte r = (byte) (b * b); // Giving correct result
byte r = (byte) b * b; // Giving error " POSSIBLE LOSS OF PRECISION"
为什么必须对b * b
加上括号?
答案 0 :(得分:25)
(byte) b * b
将第一个b
的值强制转换为byte
(是多余的,因为它已经是byte
),并将其乘以第二个b
的值。将两个byte
相乘会首先将它们提升为int
,因为*
中没有byte
运算符。因此,结果为int
,并且不能分配给byte
变量。
另一方面,(byte)(b * b)
将int
乘法结果转换为byte
,可以将其分配给byte
变量。
JLS的5.6.2. Binary Numeric Promotion中对此进行了介绍:
当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示一个可转换为数字类型的值,以下规则适用:
如果任何操作数是引用类型,则将其进行拆箱转换(第5.1.8节)。
通行基元转换(第5.1.2节)适用于转换以下规则指定的一个或两个操作数:
如果其中一个操作数的类型为double,则另一个将转换为double。
否则,如果其中一个操作数的类型为float,则另一个将转换为float。
否则,如果其中一个操作数的类型为long,则另一个将转换为long。
否则,两个操作数都将转换为int类型。。
答案 1 :(得分:6)
铸造问题
byte r = (byte) (b * b);
它将(byte)
类型转换为(b * b)
的结果
byte r = (byte) b * b;
仅将(byte)
类型转换为第一个b
,因此它将变为((byte) b) * b
答案 2 :(得分:2)
根据优先级规则,您只将第一个b强制转换为字节,而不是整个结果。
Java遵循一些规则,如您所见here
算术运算(
+
,−
,*
,/
,%
中的所有整数值(字节,短整数和整数)都将被转换在执行算术运算之前将其类型转换为int
。但是,如果算术运算中的值之一(+
,−
,*
,/
,%
)为long
,则在执行算术运算之前,所有值都将转换为long
类型。
因此,只需投射第一个b
,即可做到:
byte = byte * integer
因此:
byte = integer
因此,引发了错误。
答案 3 :(得分:0)
类型为byte
的变量必须为[-128,127],这就是为什么编译器在不强制转换结果的情况下必须不接受任何操作b*b;b+b;b-b;b/b
的原因,例如:(byte)(b*b)
在下面的代码中,当您将结果类型更改为int
时,它将进行编译。
byte b=10;
byte c=(byte)b*b; //incompatible but correct when c is int
byte d=((byte)b)*b; //incompatible but correct when d is int
byte r=(byte)(b*b);
byte t= b*b; //incompatible but correct when t is int
byte e=(byte)b/b; //incompatible but correct when e is int
byte f=((byte)b)/b; //incompatible but correct when f is int
byte o=(byte)(b/b);
byte w=b/b; //incompatible but correct when w is int
byte g=(byte)b+b; //incompatible but correct when g is int
byte p=((byte)b)+b; //incompatible but correct when p is int
byte q=(byte)(b+b);
byte x=b+b; //incompatible but correct when x is int
byte h=(byte)b-b; //incompatible but correct when h is int
byte v=((byte)b)-b; //incompatible but correct when v is int
byte s=(byte)(b-b);
byte y=b-b; //incompatible but correct when y is int
byte k=(byte)b;
byte u=b;
注意
正如@andy Truner在评论中指出的那样,当b
为final
时,除以下设置外,所有先前的指令都将编译!!
final byte fn=-120;
byte z=fn-b; //this does not compile even when both final, because the result would be -130, out of the byte type interval!!