java类型转换存在语义风险而非语法错误,需通过边界值测试、math.exact方法、截断与精度丢失验证主动防控溢出和精度问题。

Java 类型转换不是语法错误,而是语义风险——溢出和精度丢失不会编译报错,却会让数值在运行时“悄悄变样”。验证它们,关键不是等出问题再排查,而是主动设计测试用例,覆盖边界、截断、符号翻转和浮点近似等典型场景。
用边界值触发整型溢出
整型溢出本质是补码绕回,必须用刚好越界的值验证。比如 byte(-128 ~ 127),测试不能只试 128 和 -129,还要覆盖典型绕回点:
- 正向溢出:`(byte) 127 → 127`,`(byte) 128 → -128`,`(byte) 255 → -1`(255 % 256 = -1)
- 负向溢出:`(byte) (-128) → -128`,`(byte) (-129) → 127`(-129 + 256 = 127)
- 链式运算溢出:`int a = Integer.MAX_VALUE; int b = a + 1;` 结果是 `Integer.MIN_VALUE`,不是异常
用 Math.toIntExact() 捕获静默溢出
裸强转 `(int) longValue` 不报错,但结果不可信。改用 JDK 提供的检查方法,让溢出暴露为异常:
- `Math.toIntExact(2147483648L)` 直接抛 `ArithmeticException`,明确告诉你“装不下”
- 配合单元测试断言:
assertThrows(ArithmeticException.class, () -> Math.toIntExact(3000000000L)) - 对 short/byte 同理:`Math.toShortExact(intValue)`、`Math.toByteExact(intValue)`
验证浮点转整数的截断行为
`(int) 3.9` 得 3,`(int) -3.9` 得 -3 —— 这是向零截断,不是四舍五入。验证时要区分意图:
- 测试截断:`assertEquals(3, (int) 3.9); assertEquals(-3, (int) -3.9)`
- 测试四舍五入:`assertEquals(4L, Math.round(3.9)); assertEquals(-4L, Math.round(-3.9))`(注意返回 long)
- 测试 NaN/Infinity 边界:`(int) Double.NaN → 0`,`(int) Double.POSITIVE_INFINITY → Integer.MAX_VALUE`
检查浮点精度丢失的不可逆性
float 只有 23 位有效尾数,超过 2²⁴ 的整数无法精确表示。验证方式不是比相等,而是看是否“跳变”:
- `int x = 16777217; float f = x;` 断言 `f == 16777216.0f`(已丢失 +1)
- `double d = 0.1 + 0.2;` 断言 `d != 0.3`,再用 `Math.abs(d - 0.3)
- 金额场景验证:`new BigDecimal("0.1").add(new BigDecimal("0.2"))` 确实等于 `new BigDecimal("0.3")`
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











