Java基本类型强制转换会丢失精度因位数固定,高位转低位截断二进制;浮点转整数向零截断;parseInt()返回int,valueOf()返回Integer并缓存-128~127;安全转Number需instanceof检查后调xxxValue();BigDecimal转基本类型直接截断,非四舍五入。

Java中基本类型的强制转换为什么有时会丢失精度
因为Java的数值类型有固定位数,高位转低位时会截断二进制表示。比如 int 是32位,转成 byte(8位)时只保留低8位,高位信息直接丢弃。
-
int x = 257;→(byte)x结果是1(257 的二进制低8位是00000001) - 浮点转整数一律向零截断:
(int)3.9得3,(int)-3.9得-3 - 不要依赖自动提升做“安全转换”——
short s = 10; byte b = s;编译不通过,必须显式强转
Integer.parseInt() 和 Integer.valueOf() 的区别在哪
两者都把字符串转成整数,但返回类型和异常行为不同:parseInt() 返回 int 基本类型,valueOf() 返回 Integer 包装类对象,且对 -128~127 范围内的值会复用缓存实例。
- 空字符串或含非数字字符(如
"12a")都会抛NumberFormatException - 前导空格会被忽略,但前后不能有其他字符:
Integer.parseInt(" 42 ")✅,Integer.parseInt("42abc")❌ - 支持进制参数:
Integer.parseInt("1010", 2)→10,Integer.parseInt("FF", 16)→255
如何安全地将 Object 转为 Number 子类(如 Double、Long)
不能直接强转 (Double)obj,因为运行时类型可能不匹配。应先用 instanceof 检查,再调用对应包装类的 xxxValue() 方法获取基本类型值。
Object obj = 42.5;
if (obj instanceof Number) {
double d = ((Number) obj).doubleValue();
long l = ((Number) obj).longValue(); // 截断小数部分
} else if (obj instanceof String) {
try {
double d = Double.parseDouble((String) obj);
} catch (NumberFormatException e) {
// 处理解析失败
}
}
-
Number是所有数值包装类的父类,doubleValue()、longValue()等方法会做合理转换(如Integer调doubleValue()返回42.0) - 字符串转数值务必包
try-catch,NumberFormatException是运行时异常,编译器不强制处理但极易发生 - 避免用
obj.toString()再解析——如果obj是null,直接 NPE
BigDecimal 转基本类型时的精度陷阱
BigDecimal 的 intValue()、longValue() 等方法会直接截断小数,不四舍五入;而 setScale(0, RoundingMode.HALF_UP).intValue() 才等价于“四舍五入取整”。
立即学习“Java免费学习笔记(深入)”;
-
new BigDecimal("3.9").intValue()→3,不是4 -
new BigDecimal("3.5").longValueExact()抛ArithmeticException,因为longValueExact()要求无精度损失 - 涉及金额计算,别用
double中间参与运算——new BigDecimal(0.1)实际构造的是0.10000000000000000555...,应写new BigDecimal("0.1")
Number 子类——这两处一旦出错,都是运行时才暴露。










