Double.valueOf() 是 Java 中将 double 基本类型或字符串转换为 Double 对象的推荐方法。它取代了已过时的 new Double() 构造函数,是现代 Java 开发中处理 Double 对象的标准做法。
📚 一、方法定义
1. Double.valueOf(double d)
public static Double valueOf(double d)
- 功能:将
double基本类型封装为Double对象。 - 参数:
d- 要封装的double值 - 返回值:对应的
Double对象
2. Double.valueOf(String s)
public static Double valueOf(String s) throws NumberFormatException
- 功能:将字符串解析为
double,并封装为Double对象。 - 参数:
s- 表示数字的字符串 - 返回值:解析后的
Double对象 - 异常:
NumberFormatException- 字符串格式不合法
💡 二、核心优势(为什么推荐使用?)
| 优势 | 说明 |
|---|---|
| ✅ 取代过时构造函数 | new Double(...) 在 Java 9 中已标记为 @Deprecated |
| ✅ 可能使用缓存 | 虽然 Double 缓存不如 Integer 明显,但 valueOf() 为未来优化留出空间 |
| ✅ 标准编码规范 | 所有包装类(Integer, Long, Double 等)都推荐使用 valueOf() |
| ✅ 代码一致性 | 与 Integer.valueOf(), Boolean.valueOf() 等保持风格统一 |
| ✅ 自动装箱替代方案 | 在需要显式转换或解析字符串时使用 |
🧪 三、示例代码
示例 1:基本使用(double → Double)
public class DoubleValueOfExample {
public static void main(String[] args) {
// ✅ 推荐:使用 valueOf()
Double d1 = Double.valueOf(3.14);
Double d2 = Double.valueOf(-2.5);
Double zero = Double.valueOf(0.0);
System.out.println(d1); // 3.14
System.out.println(d2); // -2.5
// ⚠️ 不推荐:已过时的构造函数
// Double d3 = new Double(1.23); // 编译警告
}
}
示例 2:字符串解析(String → Double)
try {
Double d1 = Double.valueOf("3.14");
Double d2 = Double.valueOf("-2.718");
Double sci = Double.valueOf("1.23E4"); // 科学计数法 → 12300.0
Double inf = Double.valueOf("Infinity"); // 正无穷
Double nan = Double.valueOf("NaN"); // 非数字
System.out.println(d1); // 3.14
System.out.println(sci); // 12300.0
System.out.println(inf); // Infinity
System.out.println(nan); // NaN
} catch (NumberFormatException e) {
System.err.println("字符串格式错误: " + e.getMessage());
}
示例 3:自动装箱 vs valueOf()
// 三种等效写法(结果相同)
Double a1 = 3.14; // 自动装箱(最简洁)
Double a2 = Double.valueOf(3.14); // 显式 valueOf(推荐用于方法调用)
Double a3 = new Double(3.14); // ❌ 已过时,避免使用
// 在方法参数中 valueOf() 更清晰
List<Double> list = new ArrayList<>();
list.add(Double.valueOf(1.1)); // 比 list.add(1.1) 更明确意图
⚠️ 四、注意事项
1. NumberFormatException 异常处理
String[] invalid = {"abc", "3.14.15", "", "null", " "};
for (String s : invalid) {
try {
Double d = Double.valueOf(s);
System.out.println(s + " → " + d);
} catch (NumberFormatException e) {
System.err.println("无法解析 '" + s + "': " + e.getMessage());
}
}
常见错误输入:
"abc"- 非数字"3.14.15"- 多个小数点""- 空字符串"Infinityy"- 拼写错误"123abc"- 数字后跟字符
2. 特殊值支持
Double.valueOf(String) 支持以下特殊字符串(不区分大小写):
| 字符串 | 对应值 |
|---|---|
"Infinity" |
Double.POSITIVE_INFINITY |
"+Infinity" |
Double.POSITIVE_INFINITY |
"-Infinity" |
Double.NEGATIVE_INFINITY |
"NaN" |
Double.NaN |
System.out.println(Double.valueOf("infinity")); // Infinity
System.out.println(Double.valueOf("-INFINITY")); // -Infinity
System.out.println(Double.valueOf("nan")); // NaN
3. 空白字符处理
Double.valueOf(" 3.14 ")→ 抛出NumberFormatException- 必须先调用
.trim():
String input = " 3.14 ";
Double d = Double.valueOf(input.trim()); // 正确
4. null 输入
Double.valueOf(null); // 抛出 NullPointerException
🔄 五、与相关方法对比
| 方法 | 是否推荐 | 说明 |
|---|---|---|
Double.valueOf(3.14) |
✅ 推荐 | 标准做法,可能优化 |
Double.valueOf("3.14") |
✅ 推荐 | 解析字符串的标准方式 |
new Double(3.14) |
❌ 不推荐 | Java 9+ 已过时 |
new Double("3.14") |
❌ 不推荐 | 同上,且抛异常时不一致 |
3.14(自动装箱) |
✅ 推荐 | 简洁,等效于 valueOf |
Double.parseDouble("3.14") |
✅ 推荐 | 返回 double,用于计算 |
💡 选择建议:
- 需要
Double对象 → 用Double.valueOf()- 需要
double值 → 用Double.parseDouble()- 简单赋值 → 用自动装箱
Double d = 3.14;
🛠️ 六、使用技巧
1. 安全的字符串转 Double(带默认值)
public static Double safeValueOf(String s, Double defaultValue) {
if (s == null || s.trim().isEmpty()) {
return defaultValue;
}
try {
return Double.valueOf(s.trim());
} catch (NumberFormatException e) {
return defaultValue;
}
}
// 使用
Double result = safeValueOf("abc", 0.0); // 返回 0.0
2. 在集合操作中的应用
// 正确:向 List 添加 Double
List<Double> scores = new ArrayList<>();
scores.add(Double.valueOf(95.5));
scores.add(Double.valueOf(87.2));
// 或使用自动装箱
scores.add(92.8);
3. 与 Optional 结合(防 null)
Optional<Double> parseDouble(String s) {
try {
return Optional.of(Double.valueOf(s.trim()));
} catch (Exception e) {
return Optional.empty();
}
}
// 使用
Optional<Double> opt = parseDouble("3.14");
opt.ifPresent(System.out::println);
📊 七、性能考虑
Double.valueOf(double)性能与new Double()相当,但为未来优化留出空间Double.valueOf(String)内部调用Double.parseDouble(),性能开销主要在字符串解析- 在高频循环中,应优先使用
double原生类型,避免频繁装箱
// 慢:频繁装箱
List<Double> list = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
list.add(Double.valueOf(i * 0.1)); // 创建 10 万个对象
}
// 快:使用原生数组
double[] arr = new double[100000];
for (int i = 0; i < 100000; i++) {
arr[i] = i * 0.1;
}
📝 八、总结
| 项目 | 内容 |
|---|---|
| 核心作用 | 将 double 或字符串安全转换为 Double 对象 |
| 推荐场景 | 所有需要创建 Double 对象的场合 |
| 替代对象 | new Double(...) 构造函数(已过时) |
| 关键优势 | 标准化、可能优化、与自动装箱一致 |
| 异常处理 | NumberFormatException(字符串解析失败)、NullPointerException(null 输入) |
| 特殊值支持 | Infinity, -Infinity, NaN(不区分大小写) |
| 最佳实践 | 优先使用 valueOf() 或自动装箱,避免构造函数 |
✅ 一句话掌握:
用
Double.valueOf(3.14)或Double.valueOf("3.14")创建Double对象,永远不要用new Double(...),字符串解析记得trim()和try-catch。