在Java中如何进行数值类型转换_Java类型转换规则说明

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.93(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)10Integer.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() 等方法会做合理转换(如 IntegerdoubleValue() 返回 42.0
  • 字符串转数值务必包 try-catchNumberFormatException 是运行时异常,编译器不强制处理但极易发生
  • 避免用 obj.toString() 再解析——如果 objnull,直接 NPE

BigDecimal 转基本类型时的精度陷阱

B

igDecimalintValue()longValue() 等方法会直接截断小数,不四舍五入;而 setScale(0, RoundingMode.HALF_UP).intValue() 才等价于“四舍五入取整”。

  • 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 子类——这两处一旦出错,都是运行时才暴露。