核心概念

  1. 类型差异
    • int/long:整数类型(long范围更大)
    • double:双精度浮点数(可能有精度损失)
    • BigDecimal:高精度小数(适用于金融计算)
  2. 异常处理:转换失败时抛出 NumberFormatException
  3. 空值处理null 字符串会引发 NullPointerException

详细操作步骤

1. String → int

// 方法1:Integer.parseInt()
String strInt = "123";
int numInt = Integer.parseInt(strInt);

// 方法2:Integer.valueOf() + intValue()
Integer integerObj = Integer.valueOf(strInt);
int numInt = integerObj.intValue();

// 含进制转换(如16进制)
int hexInt = Integer.parseInt("FF", 16); // 输出255

2. String → long

// 方法1:Long.parseLong()
String strLong = "9876543210";
long numLong = Long.parseLong(strLong);

// 方法2:Long.valueOf()
Long longObj = Long.valueOf(strLong);
long numLong = longObj.longValue();

// 含进制转换
long binLong = Long.parseLong("1010", 2); // 输出10

3. String → double

// 方法1:Double.parseDouble()
String strDouble = "123.456";
double numDouble = Double.parseDouble(strDouble);

// 方法2:Double.valueOf()
Double doubleObj = Double.valueOf(strDouble);
double numDouble = doubleObj.doubleValue();

// 科学计数法支持
double sciDouble = Double.parseDouble("1.23e4"); // 输出12300.0

4. String → BigDecimal(高精度小数)

import java.math.BigDecimal;

// 直接构造(推荐!避免double精度问题)
String strDecimal = "123.4567890123456789";
BigDecimal decimal = new BigDecimal(strDecimal);

// 通过Double转换(不推荐,可能损失精度)
BigDecimal badDecimal = BigDecimal.valueOf(Double.parseDouble(strDecimal)); // ❌ 避免

常见错误与解决方案

错误场景 异常类型 解决方案
字符串包含非数字字符 NumberFormatException 使用正则校验:str.matches("-?\\d+(\\.\\d+)?")
空字符串 "" NumberFormatException 前置检查:if(!str.isEmpty())
字符串为 null NullPointerException 空值检查:if(str != null)
超出类型范围(如300亿转int) NumberFormatException 改用longBigInteger
小数点转整数类型 NumberFormatException 先转double再取整(需业务逻辑)

关键注意事项

  1. 精度陷阱
    • double 有精度损失(如 0.1 + 0.2 != 0.3
    • 金融计算必须用 BigDecimal
  2. 本地化问题
    • 某些地区用 , 分隔小数点(如 "123,45"
    • 解决方案:
      NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
      double d = format.parse("123,45").doubleValue();
      
  3. 性能考量
    • parseInt()valueOf() 略快(少一步装箱)
    • BigDecimal 构造开销较大,避免高频调用

最佳实践与性能优化

  1. 防御性编程
    public static int safeParseInt(String str, int defaultValue) {
        if (str == null) return defaultValue;
        try {
            return Integer.parseInt(str.trim()); // 去除空格
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }
    
  2. 正则预校验(适用于严格场景):
    // 校验整数格式
    boolean isValidInt = str.matches("-?\\d+");
    
    // 校验浮点数格式
    boolean isValidDouble = str.matches("-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?");
    
  3. BigDecimal使用规范
    • 始终用字符串构造new BigDecimal("0.1")
    • 禁止用double构造:new BigDecimal(0.1) ❌(精度已损失)
    • 运算时指定舍入模式:
      BigDecimal a = new BigDecimal("10");
      BigDecimal b = new BigDecimal("3");
      BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP); // 3.33
      

性能对比(纳秒/次)

方法 JDK 17 平均耗时
Integer.parseInt() 15 ns
Long.parseLong() 18 ns
Double.parseDouble() 45 ns
new BigDecimal() 120 ns

优化建议:高频场景优先使用基本类型方法(parseInt/parseLong


完整工具类示例

import java.math.BigDecimal;

public class NumberUtils {
    // String → int(带默认值)
    public static int toInt(String str, int defaultValue) {
        if (str == null) return defaultValue;
        try {
            return Integer.parseInt(str.trim());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }
    
    // String → BigDecimal(安全转换)
    public static BigDecimal toBigDecimal(String str) {
        if (str == null || str.trim().isEmpty()) 
            return BigDecimal.ZERO;
        try {
            return new BigDecimal(str.trim());
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }
    
    // 其他类型类似实现...
}

使用示例:int id = NumberUtils.toInt(userInput, -1);


总结要点

  1. 基础类型转换:用 parseXxx() 方法(Integer.parseInt()
  2. 高精度需求:必用 BigDecimal(String)
  3. 异常处理:始终捕获 NumberFormatException
  4. 输入清理:转换前调用 trim() 去除空格
  5. 性能敏感场景:避免频繁创建 BigDecimal

通过遵循这些实践,可高效安全地实现字符串到数值的转换,同时规避常见陷阱。