Java强制类型转换不校验溢出,整数转小类型取低N位按补码重解释,浮点转整数先向零截断再整型截断,无符号数据需用位运算避免符号误读。

Java 强制类型转换溢出不报错,也不做校验,结果完全由底层二进制截断规则决定:只保留目标类型的低位字节,并按该类型的补码规则重新解释。计算本质是“位截断 + 补码重解读”,不是数学意义上的取模或四舍五入。
整数转小类型:取低 N 位补码
例如 int → byte:int 占 4 字节(32 位),byte 占 1 字节(8 位)。转换时丢弃高 24 位,仅保留低 8 位,再将这 8 位当作 byte 的补码来解读。
-
(byte)130:130 的 int 补码是00000000 00000000 00000000 10000010,取低 8 位得10000010;这是负数补码,反推原码为11111110,即 −126 -
(byte)200:200 的低 8 位是11001000,补码解释为 −56 -
(byte)256:256 的二进制是00000001 00000000,低 8 位全 0 →00000000→ 0
浮点转整数:向零截断,再按整型范围处理
先丢弃小数部分(不是四舍五入),再将整数部分强制转为目标整型——此时若超出范围,仍会触发整型截断。
-
(int)3.9→ 先得 3,再转 int → 3 -
(int)-3.9→ 先得 −3,再转 int → −3 -
(int)3e9:3e9 ≈ 3,000,000,000 > Integer.MAX_VALUE(2,147,483,647),所以先截小数得 3000000000,再转 int → 取低 32 位补码 → −1294967296
无符号数据误当有符号:高位被当符号位
Java 没有 uint8,但协议中常有 0xFF(本意是 255)。直接 (byte)0xFF 得到的是 −1,因为 11111111 被解释为 byte 补码。
立即学习“Java免费学习笔记(深入)”;
- 正确做法:
int value = b & 0xFF,利用按位与把高 24 位清零,保留低 8 位并升为正数 int - 类似地,
short s = (short)0xFFFF得 −1;若想表示无符号 65535,应写int u = s & 0xFFFF
怎么快速预判结果?用位运算模拟
对任意整型转 n 位有符号类型(如 byte 是 8 位、short 是 16 位),可统一用公式:
- 转 byte:
value & 0xFF,再按 byte 补码解释(即:若结果 ≥ 128,则减去 256) - 转 short:
value & 0xFFFF,若结果 ≥ 32768,则减去 65536 - 更稳妥:直接用
Math.toByteExact(value)或Math.toIntExact(value),越界立即抛异常,不靠手算


















