核心概念
- 类型差异:
int
/long
:整数类型(long
范围更大)double
:双精度浮点数(可能有精度损失)BigDecimal
:高精度小数(适用于金融计算)
- 异常处理:转换失败时抛出
NumberFormatException
- 空值处理:
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 |
改用long 或BigInteger |
小数点转整数类型 | NumberFormatException |
先转double 再取整(需业务逻辑) |
关键注意事项
- 精度陷阱:
double
有精度损失(如0.1 + 0.2 != 0.3
)- 金融计算必须用
BigDecimal
- 本地化问题:
- 某些地区用
,
分隔小数点(如"123,45"
) - 解决方案:
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE); double d = format.parse("123,45").doubleValue();
- 某些地区用
- 性能考量:
parseInt()
比valueOf()
略快(少一步装箱)BigDecimal
构造开销较大,避免高频调用
最佳实践与性能优化
- 防御性编程:
public static int safeParseInt(String str, int defaultValue) { if (str == null) return defaultValue; try { return Integer.parseInt(str.trim()); // 去除空格 } catch (NumberFormatException e) { return defaultValue; } }
- 正则预校验(适用于严格场景):
// 校验整数格式 boolean isValidInt = str.matches("-?\\d+"); // 校验浮点数格式 boolean isValidDouble = str.matches("-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?");
- 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);
总结要点
- 基础类型转换:用
parseXxx()
方法(Integer.parseInt()
) - 高精度需求:必用
BigDecimal(String)
- 异常处理:始终捕获
NumberFormatException
- 输入清理:转换前调用
trim()
去除空格 - 性能敏感场景:避免频繁创建
BigDecimal
通过遵循这些实践,可高效安全地实现字符串到数值的转换,同时规避常见陷阱。