在 Java 开发中,最常见的需求之一就是在 String(字符串)和基本数字类型(如 int, long, double 等)以及它们对应的包装类(Integer, Long, Double 等)之间进行转换。

核心概念
- 基本数据类型:Java 提供的 8 种基本数据类型之一,用于表示数值。
int,long,double,float。 - 包装类:每个基本数据类型都有一个对应的类(包装类)。
int的包装类是Integer,double的包装类是Double,包装类提供了很多有用的方法,并且可以支持null值。 - 字符串:
String类是 Java 中用于表示字符序列的类,它是一个不可变的对象。
将数字类型转换为 String
有几种方法可以将数字转换为字符串,其中最常用和推荐的是第一种。
使用 String.valueOf() (推荐)
这是最简洁、最安全的方法,它是一个静态方法,可以直接作用于基本数据类型或包装类。
int number = 123; String str1 = String.valueOf(number); // 将 int 转为 String System.out.println(str1); // 输出: 123 double d = 123.45; String str2 = String.valueOf(d); // 将 double 转为 String System.out.println(str2); // 输出: 123.45 // 也可以用于包装类 Integer integerObj = 456; String str3 = String.valueOf(integerObj); System.out.println(str3); // 输出: 456
使用 toString() 方法
每个包装类都重写了 Object 类的 toString() 方法,用于返回该对象的字符串表示。
int number = 789; // 1. 先将基本类型转为包装类 Integer integerObj = number; // 2. 再调用 toString() String str = integerObj.toString(); System.out.println(str); // 输出: 789 // 或者直接使用基本类型的字面量 String str2 = 1000.50 + ""; // 利用字符串拼接,底层会自动调用 toString() System.out.println(str2); // 输出: 1000.5
注意:直接对基本数据类型(如 int)调用 .toString() 是错误的,因为基本类型没有方法,必须先将其转换为包装类。

使用空字符串拼接(简单但不推荐)
这是一种快捷方式,利用了 Java 的字符串自动转换特性。
int number = 2025; String str = number + ""; // 隐式调用 Integer.toString() System.out.println(str); // 输出: 2025
为什么不推荐?
- 可读性差:
String.valueOf(number)的意图比number + ""更清晰。 - 性能略低:在底层,这种方式会创建一个新的
StringBuilder对象来完成拼接,虽然性能差异通常可以忽略,但在性能极其敏感的代码中,valueOf可能更优。
将 String 转换为数字类型
这是更常见也更容易出错的操作,因为字符串的格式可能不正确。
基本方法:使用包装类的 parseXxx() 或 valueOf() 方法
所有包装类都有两个核心的静态方法用于将字符串转换为数字:
static int parseInt(String s): 将字符串解析为int基本类型。static Integer valueOf(String s): 将字符串解析为Integer包装类对象。
Double, Long 等类也提供类似的 parseDouble(), parseLong(), valueOf() 方法。
成功案例
String intStr = "123"; String doubleStr = "98.76"; // 转换为基本类型 int int num1 = Integer.parseInt(intStr); System.out.println(num1); // 输出: 123 System.out.println(num1 + 100); // 输出: 223 // 转换为包装类 Integer Integer num2 = Integer.valueOf(intStr); System.out.println(num2); // 输出: 123 System.out.println(num2.getClass().getName()); // 输出: java.lang.Integer // 转换为基本类型 double double d1 = Double.parseDouble(doubleStr); System.out.println(d1); // 输出: 98.76 // 转换为包装类 Double Double d2 = Double.valueOf(doubleStr); System.out.println(d2); // 输出: 98.76
关键:处理异常 NumberFormatException
如果字符串的格式不正确,这些方法会抛出 NumberFormatException 异常。必须使用 try-catch 块来处理这种可能性。
String invalidStr = "abc123";
try {
int num = Integer.parseInt(invalidStr);
System.out.println("转换成功: " + num);
} catch (NumberFormatException e) {
System.out.println("错误: 字符串 '" + invalidStr + "' 不是有效的整数。");
// e.printStackTrace(); // 打印详细的错误堆栈
}
// 对浮点数同样适用
String invalidDoubleStr = "12.3.4";
try {
double d = Double.parseDouble(invalidDoubleStr);
System.out.println("转换成功: " + d);
} catch (NumberFormatException e) {
System.out.println("错误: 字符串 '" + invalidDoubleStr + "' 不是有效的浮点数。");
}
进阶方法:使用 Number 类和 Scanner
Scanner 类
Scanner 类提供了一种更灵活的方式来解析输入,它不仅能处理数字,还能处理各种分隔符。
String input = "100 200 300.5 400.75";
Scanner scanner = new Scanner(input);
// 按空格分隔
while (scanner.hasNext()) {
if (scanner.hasNextInt()) {
int i = scanner.nextInt();
System.out.println("整数: " + i);
} else if (scanner.hasNextDouble()) {
double d = scanner.nextDouble();
System.out.println("浮点数: " + d);
} else {
// 如果既不是整数也不是浮点数,就跳过
scanner.next();
}
}
scanner.close();
// 输出:
// 整数: 100
// 整数: 200
// 浮点数: 300.5
// 浮点数: 400.75
Number 类和 NumberFormatException
Integer, Double 等都是 Number 类的子类,如果你想让代码更通用,可以捕获 NumberFormatException 并返回 null 或一个默认值。
public static Integer parseIntegerSafely(String str) {
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
return null; // 或者返回一个默认值,如 0
}
}
String testStr1 = "50";
String testStr2 = "hello";
Integer result1 = parseIntegerSafely(testStr1);
Integer result2 = parseIntegerSafely(testStr2);
System.out.println(result1); // 输出: 50
System.out.println(result2); // 输出: null
格式化数字为字符串 (高级)
有时,我们需要将数字格式化为特定格式的字符串,例如保留两位小数、添加千位分隔符等,这时可以使用 String.format() 或 DecimalFormat 类。
使用 String.format()
double price = 12345.6789;
// 保留两位小数,四舍五入
String formattedPrice1 = String.format("%.2f", price);
System.out.println(formattedPrice1); // 输出: 12345.68
// 整数,补零
int id = 7;
String formattedId = String.format("%05d", id); // 总宽度为5,不足补0
System.out.println(formattedId); // 输出: 00007
使用 DecimalFormat 类
DecimalFormat 提供了更强大的格式化功能。
import java.text.DecimalFormat;
import java.text.NumberFormat;
double value = 1234567.891;
// 创建格式化器
DecimalFormat df1 = new DecimalFormat("#,###.00"); // 千位分隔符,两位小数
String formatted1 = df1.format(value);
System.out.println(formatted1); // 输出: 1,234,567.89
DecimalFormat df2 = new DecimalFormat("0.00%"); // 百分比格式
String formatted2 = df2.format(0.789);
System.out.println(formatted2); // 输出: 78.90%
总结与最佳实践
| 场景 | 推荐方法 | 示例 | 注意事项 |
|---|---|---|---|
| 数字 -> String | String.valueOf() |
String s = String.valueOf(123); |
最推荐,简洁高效。 |
toString() |
String s = Integer.valueOf(123).toString(); |
需要先转包装类。 | |
| String -> 数字 | 包装类.parseXxx() |
int i = Integer.parseInt("123"); |
必须用 try-catch 处理异常。 |
包装类.valueOf() |
Integer i = Integer.valueOf("123"); |
同样需要处理异常,返回包装类对象。 | |
| 格式化数字 | String.format() |
String s = String.format("%.2f", 123.456); |
简单格式化,类似 C 语言的 printf。 |
DecimalFormat |
DecimalFormat df = new DecimalFormat("#,##0.00"); |
功能强大,适合复杂的本地化格式化。 |
核心要点:
String.valueOf()是数字转字符串的首选。- 字符串转数字时,永远不要忘记处理
NumberFormatException,这是 Java 开发中的一个基本防御性编程原则。 - 根据你的需求选择合适的方法:简单转换用
parseXxx,需要更健壮的错误处理可以封装一个工具方法,复杂的格式化用DecimalFormat。
