我知道编译器对整数文字进行隐式类型转换.例如:
byte b = 2; // implicit type conversion, same as byte b = (byte)2;
Run Code Online (Sandbox Code Playgroud)
如果范围溢出,编译器会给出错误:
byte b = 150; // error, it says cannot convert from int to byte
Run Code Online (Sandbox Code Playgroud)
当变量传递表达式时,编译器会给出相同的错误:
byte a = 3;
byte b = 5;
byte c = 2 + 7; // compiles fine
byte d = 1 + b; // error, it says cannot convert from int to byte
byte e = a + b; // error, it says cannot convert from int to byte
Run Code Online (Sandbox Code Playgroud)
我得出的结论是,无法保证涉及变量的表达式的结果.结果值可以在字节范围之内或之外,因此编译器会抛出错误.
令我困惑的是,当我这样说时,编译器不会抛出错误:
byte a = 127;
byte b = 5;
byte z = (a+=b); // no error, why ?
Run Code Online (Sandbox Code Playgroud)
为什么不给我一个错误?
Mak*_*oto 22
虽然反编译你的代码将解释什么 Java正在做,原因为什么它做它通常可以在语言规范中.但在我们进入之前,我们必须建立一些重要的概念:
如果整数文字后缀为ASCII字母L或l(ell),则整数文字的长度为long; 否则它的类型为int(§4.2.1).
尝试分配大于可以容纳它的类型的文字将导致编译错误.这是您遇到的第一个场景.
所以我们回到这种情况:为什么要添加两个明显多于字节可以处理的字节而不会产生编译错误?
这是两个加在一起的数字突然产生一个非常小的数字的情况.由于体积小byte,所以很容易溢出; 例如,添加1到127会这样做,结果为-128.
它将要解决的主要原因是Java处理原始值转换的方式; 在这种情况下,我们谈论的是缩小转换.也就是说,即使产生的总和更大的比byte,缩小转换将导致信息被丢弃允许数据以适应一个byte,因为这种转换从来没有导致运行时异常.
要逐步分解您的场景:
a = 127并b = 5一起生成132.a并且b是类型的byte,因此结果也必须是类型byte.(byte)(a += b).a和z包含结果-124由于环绕.我得出的结论是,无法保证涉及变量的表达式的结果.结果值可以在字节范围之内或之外,因此编译器会抛出错误.
不,那不是原因.静态类型语言的编译器以这种方式工作:必须声明和键入任何变量,因此即使在编译时未知其值,其类型也是已知的.隐式常量也是如此.基于这个事实,计算尺度的规则基本上是:
(这些实际上是一个简化的视图;实际上可能有点复杂).
将它应用于您的案例:
byte d = 1 + b
Run Code Online (Sandbox Code Playgroud)
实际比例是:
byte = int + byte
Run Code Online (Sandbox Code Playgroud)
...(因为1被视为隐式int常量).因此,应用第一个规则,变量必须至少具有int比例.
在这种情况下:
byte z = (a+=b);
Run Code Online (Sandbox Code Playgroud)
实际比例是:
byte = byte += byte
Run Code Online (Sandbox Code Playgroud)
......没关系.
更新
那么,为什么会byte e = a + b产生编译时错误?
正如我所说的,在Java的实际类型规则更复杂的:虽然一般规则适用于所有类型的,原始byte和short类型是更受限制:编译器假定加法/从其减去两个或多个字节/短裤是冒着引起上溢(正如@Makoto所说),因此需要将其存储为被认为"更安全"的下一类型:a int.
答案由JLS 15.26.2提供:
例如,以下代码是正确的:
short x = 3;
x += 4.6;并且结果x的值为7,因为它相当于:
short x = 3;
x = (short)(x + 4.6);
因此,正如您所看到的,最新的情况实际上是有效的,因为添加赋值(与任何其他运算符赋值一样)对左手类型执行隐式强制转换(在您的情况下a为a byte).扩展,相当于byte e = (byte)(a + b);,将编译愉快.
| 归档时间: |
|
| 查看次数: |
3106 次 |
| 最近记录: |