byte b=9 ;
b=b+6 ;给出编译错误(可能的精度损失)为什么b=9不给出错误,而b=b+9给出精度损失?
有人告诉我,9 (或任何数字)被视为int,因此会损失精度。但是为什么b=9没有给出任何精度误差损失呢?
此外,当编写为b+=6时,代码不会给出任何错误。b=b+6和b+=6有什么不同?
有没有人可以解释一下这些错综复杂的地方,或者添加一个我可以研究它们的链接?
发布于 2014-07-16 02:00:22
此代码给出一个错误...
byte b=9;
b=b+6;..。这是因为b+6中发生了二进制数字提升,它将b提升为int以添加数量。Section 5.6.2 of the JLS谈到这一点:
当运算符对一对操作数应用二进制数值提升时,每个操作数必须表示一个可转换为数值类型的值,请按顺序应用以下规则:
- If either operand is of type double, the other is converted to double.
- Otherwise, if either operand is of type float, the other is converted to float.
- Otherwise, if either operand is of type long, the other is converted to long.
- **Otherwise, both operands are converted to type int**.
(强调我的)
要编译b=b+6,可以显式地将结果转换回byte
b = (byte) (b + 6);但是b=9和b+=6呢?为什么他们编译的时候没有错误?
9是一个常量表达式,在缩小赋值范围方面,Java编译器以不同的方式对待它。
Section 5.2 of the JLS谈到了赋值转换。
此外,如果表达式是byte、short、char或int类型的常量表达式(§15.28):
如果变量的类型是byte、short或char,并且常量表达式的值可以在变量的类型中表示,则可以使用缩小原语转换。
如果它是一个常量表达式,那么它可以被缩小,这样编译器就知道这个值,并且它知道不会发生溢出。这就是为什么b=9不是错误的原因。
Section 15.26 of the JLS谈到了复合赋值操作符。
形式为E1 op= E2的复合赋值表达式等同于E1 = (T) (( E1 ) op (E2)),其中T是E1的类型,只是E1只计算一次。
也就是说,即使结果被提升为int,也会被隐式地转换回byte。请注意,这可能会在没有错误的情况下溢出;byte += 10009将在溢出时“成功”。
发布于 2014-07-16 02:02:48
表达式
b = b + 6是作为og JLS §4.2.2的整数运算。如JLS中所述,每个这样的操作都是int或long类型(这里:int)。因此,结果也是int类型,如果要将其赋给这样的变量,则必须将其强制转换为byte。
另一方面,JLS §15.26.2解释了复合赋值运算符的规则。简而言之:
形式为E1 op= E2的复合赋值表达式等同于E1 = (T) (( E1 ) op (E2)),其中T是E1的类型,只是E1只计算一次。
这清楚地告诉我们,复合赋值操作符+=隐式地执行类型转换。
发布于 2014-07-16 01:50:39
在表达式计算期间,由于java中的提升规则,会有一个隐式类型转换为int。
因此,包括:
byte b=1;
b=b+1; //will give error写入:
b=(byte)b+1;这里有一些你可以参考的链接:
Link 1
Link 2
Link 3
https://stackoverflow.com/questions/24764821
复制相似问题