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