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
。