java - 为什么这个字节没有异常?

java - why does this byte cause no exception?

我初始化一个字节如下:

byte b = (byte) 0b11110000000;

由于一个字节是 8 位大小,我预计它会抛出一些异常或错误,因为这个数字应该只能分配给 short 或以上。仍然评估为-124?或者这可能是 "normal" 行为? (没有抛出异常,但变量溢出)?

你应该得到 -128.

当您显式地将 int 转换为 byte 时,将采用最低 8 位,其余的将被丢弃。

在您的示例中,最低 8 位是 10000000,该数字的十进制值为 -128

如果没有显式转换,代码将无法通过编译,因为您的赋值会导致信息丢失。

此处:

byte b = (byte) 0b11110000000;

0b11110000000 是一个 int 字面量,正在缩小转换为 byte.

一个字节是一个 8 位有符号二进制补码整数。
它的最小值为-128,最大值为127。
字节表示的最大值为

 1111111

10000000 

溢出最大值 1。 因此,它溢出到下一个值,即 byte 的最小值:-128

记住你正在投射:

(byte) 0b11110000000;

(MSB) 位 8 之后的所有其他内容都将被丢弃...

这意味着:所有以下字节初始化将被截断为 -128(1000_0000 或第一个 8 位)

byte b = (byte) 0b1000_0000;
System.out.println(b);

b = (byte) 0b1111_1000_0000;
System.out.println(b);

b = (byte) 0b1111_1111_1000_0000;
System.out.println(b);

b = (byte) 0b1111_1111_1111_1000_0000;
System.out.println(b);

b = (byte) 0b1111_1111_1111_1111_1000_0000;
System.out.println(b);

b = (byte) 0b1111_1111_1111_1111_1111_1000_0000;
System.out.println(b);

b = (byte) 0b1111_1111_1111_1111_1111_1111_1000_0000;
System.out.println(b);

// even here with longs as bin
b = (byte) 0b1111_1111_1111_1111_1111_1111_1111_1000_0000L;
System.out.println(b);

如果你想看到错误,去掉强制转换。

byte b = 0b11110000000;

那会给你 "incompatible types: possible lossy conversion from int to byte."

由于您使用 (byte) 显式转换该值,Java 编译器假定您知道自己在做什么。

我认为这叫做加宽原始转换。

5.1.2。扩大原始转换

19 种原始类型的特定转换称为扩展原始类型转换:

byte 到 short、int、long、float 或 double

详情可以参考这个link: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html