杰瑞科技汇

Java String转Double,如何避免精度丢失?

使用 Double.parseDouble(String s) (最常用)

这是最直接、最常用的方法,它是一个静态方法,专门用于将 String 解析为 double 原始类型。

Java String转Double,如何避免精度丢失?-图1
(图片来源网络,侵删)

语法

double doubleValue = Double.parseDouble(String str);

示例代码

public class StringToDouble {
    public static void main(String[] args) {
        String strNumber = "123.456";
        String strPi = "3.14159";
        try {
            // 将字符串转换为 double
            double num1 = Double.parseDouble(strNumber);
            double num2 = Double.parseDouble(strPi);
            System.out.println("字符串: " + strNumber + " -> double: " + num1);
            System.out.println("字符串: " + strPi + " -> double: " + num2);
            // 可以进行数学运算
            double sum = num1 + num2;
            System.out.println("它们的和是: " + sum);
        } catch (NumberFormatException e) {
            System.out.println("错误: 字符串 '" + strNumber + "' 不是有效的数字格式。");
        }
    }
}

输出

字符串: 123.456 -> double: 123.456
字符串: 3.14159 -> double: 3.14159
它们的和是: 126.59759

使用 Double.valueOf(String s) (返回包装类 Double)

这个方法同样将 String 解析为 double,但它返回的是 Double 对象(即 double 的包装类),而不是原始的 double 类型。

语法

Double doubleObject = Double.valueOf(String str);

如果你需要的是原始类型 double,你还需要再调用一次 .doubleValue() 方法。

示例代码

public class StringToDoubleWrapper {
    public static void main(String[] args) {
        String strNumber = "98.76";
        try {
            // 1. 直接获取 Double 对象
            Double doubleObj1 = Double.valueOf(strNumber);
            System.out.println("Double 对象: " + doubleObj1);
            System.out.println("对象类型: " + doubleObj1.getClass().getName());
            // 2. 从 Double 对象获取原始 double 值
            double primitiveDouble = doubleObj1.doubleValue();
            System.out.println("原始 double 值: " + primitiveDouble);
            System.out.println("原始类型: " + ((Object)primitiveDouble).getClass().getName());
        } catch (NumberFormatException e) {
            System.out.println("错误: 字符串 '" + strNumber + "' 不是有效的数字格式。");
        }
    }
}

输出

Double 对象: 98.76
对象类型: java.lang.Double
原始 double 值: 98.76
原始类型: java.lang.Double

(注意:在Java中,所有原始类型在对象上下文中都会被自动装箱为其对应的包装类,所以primitiveDouble的类型显示为java.lang.Double是正常的。)


重要:异常处理 (NumberFormatException)

如果字符串不是一个有效的 double 表示形式(包含非数字字符、为空或为 null),上述两种方法都会抛出 NumberFormatException 异常。在生产代码中,你必须使用 try-catch 块来处理这种可能性。

Java String转Double,如何避免精度丢失?-图2
(图片来源网络,侵删)

常见的无效格式示例

String invalidStr1 = "hello";       // 包含非数字字符
String invalidStr2 = "123.45.67";   // 包含多个小数点
String invalidStr3 = "12a34";       // 包含字母
String invalidStr4 = "";            // 空字符串
String invalidStr5 = null;          // null 值

处理异常的完整示例

public class SafeStringToDouble {
    public static void main(String[] args) {
        String[] testStrings = {"123.45", "-99.99", "abc", "1,000.50", "", null};
        for (String str : testStrings) {
            System.out.print("尝试转换 '" + str + "': ");
            try {
                // 使用 parseDouble,因为它更常用,直接返回原始类型
                double value = Double.parseDouble(str);
                System.out.println("成功,结果为: " + value);
            } catch (NumberFormatException e) {
                System.out.println("失败 - 格式不正确");
            } catch (NullPointerException e) {
                System.out.println("失败 - 字符串为 null");
            }
        }
    }
}

输出

尝试转换 '123.45': 成功,结果为: 123.45
尝试转换 '-99.99': 成功,结果为: -99.99
尝试转换 'abc': 失败 - 格式不正确
尝试转换 '1,000.50': 失败 - 格式不正确
尝试转换 '': 失败 - 格式不正确
尝试转换 'null': 失败 - 字符串为 null

注意Double.parseDouble() 会抛出 NumberFormatException,但不会直接处理 null,传入 null 会导致 NullPointerException,在捕获 NumberFormatException 的同时,最好也捕获 NullPointerException,或者在转换前先检查字符串是否为 null


最佳实践与选择

特性 Double.parseDouble() Double.valueOf()
返回类型 原始类型 double 包装类 Double
性能 稍快,因为不需要创建额外的对象 稍慢,因为需要创建 Double 对象
主要用途 当你明确需要一个原始类型 double 进行数学计算时 当你需要一个 Double 对象,例如放入 List<Double> 或作为泛型类型时
异常 抛出 NumberFormatException 抛出 NumberFormatException

如何选择?

  1. 首选 Double.parseDouble():在 95% 的情况下,你都应该使用 Double.parseDouble(),因为它直接返回你需要的原始类型,性能更好,并且代码意图更清晰——你就是要进行数值计算。

  2. 使用 Double.valueOf():当你需要一个 Double 对象时才使用它,这种情况通常包括:

    • 当你需要将值存入一个只能存放对象的集合中时(List<Double>, Set<Double>)。
    • 当你需要利用 Double 类提供的实用方法时(isNaN(), isInfinite())。
    • 当你使用泛型且类型参数必须是包装类时。

特殊情况:处理带逗号的数字

在某些地区,数字使用逗号作为千位分隔符("1,000.50")。Double.parseDouble() 无法直接处理这种格式,它会抛出异常。

Java String转Double,如何避免精度丢失?-图3
(图片来源网络,侵删)

你需要先移除这些非数字字符。

public class ParseLocalizedNumber {
    public static void main(String[] args) {
        String numberWithComma = "1,234,567.89";
        // 移除所有逗号
        String cleanNumber = numberWithComma.replace(",", "");
        try {
            double value = Double.parseDouble(cleanNumber);
            System.out.println("转换成功: " + value); // 输出: 1234567.89
        } catch (NumberFormatException e) {
            System.out.println("转换失败");
        }
    }
}
  • 最常用、最推荐double d = Double.parseDouble(myString);
  • 必须处理异常:始终将调用包裹在 try-catch 块中,以捕获 NumberFormatExceptionNullPointerException
  • 选择合适的方法:如果需要原始类型用 parseDouble,如果需要对象用 valueOf
  • 处理特殊格式:对于带逗号或其它区域符号的数字,先进行字符串清理再转换。
分享:
扫描分享到社交APP
上一篇
下一篇