Java NumberFormat不';t使用2个十进制分隔符崩溃

Java NumberFormat不';t使用2个十进制分隔符崩溃,java,number-formatting,Java,Number Formatting,我有一个关于NumberFormat的行为的问题: 当我想将格式化的字符串转换/解析为数字时,我想使用NumberFormat,因为它为我提供了很好的千位和十进制分隔符预设。此外,如果提供的字符串不是有效的数字,我希望它崩溃 例如: // works as expected String testInput1 = "3,1415"; NumberFormat germanNumberFormat = NumberFormat.getInstance(Locale.GERMANY); Number

我有一个关于
NumberFormat
的行为的问题:

当我想将格式化的
字符串
转换/解析为
数字
时,我想使用
NumberFormat
,因为它为我提供了很好的千位和十进制分隔符预设。此外,如果提供的
字符串
不是有效的
数字
,我希望它崩溃

例如:

// works as expected
String testInput1 = "3,1415";
NumberFormat germanNumberFormat = NumberFormat.getInstance(Locale.GERMANY);
Number number1 = germanNumberFormat.parse(testInput1);
System.out.println(number1); // prints 3.1415

// does not work as expected, cuts off the number after the 2nd decimal
// separator, expected it to crash with java.lang.NumberFormatException:
// multiple points
String testInput2 = "3,14,15";
Number number2 = germanNumberFormat.parse(testInput2);
System.out.println(number2); // prints 3.14
我目前使用
Double.parseDouble(字符串s)
,以实现以下附加行为:

// crashes with java.lang.NumberFormatException: multiple points
double number2WithError = Double.parseDouble(testInput2.replace(",", "."));
除了编写自己的包装器类(对多个小数点分隔符等进行额外检查)之外,还有什么方法可以使用
NumberFormat
来实现我所需/预期的行为


我还知道,所使用的
parse(字符串源代码)
方法
NumberFormat
的JavaDoc说明:

从给定字符串的开头解析文本以生成数字。该方法不能使用给定字符串的整个文本。 有关数字解析的更多信息,请参见{@link#parse(String,ParsePosition)}方法

parse(字符串源,ParsePosition ParsePosition)

如果可能,返回一个Long(例如,在[Long.MIN_值,Long.MAX_值]范围内且不带小数),否则返回一个Double。如果设置了IntegerOnly,将在小数点处停止(或等效值;例如,对于有理数“1 2/3”,将在1之后停止)。不抛出异常;如果没有对象可以被解析,索引是不变的

但这并没有告诉我为什么方法会这样。我从中得到的是,他们只能解析
字符串的一部分(他们在这里显然是这样做的),并且可能只是从开始(开始位置)开始解析,直到他们发现一些他们无法处理的东西


我没有发现一个现有的问题涉及到这一点,因此如果已经有一个问题,请随时关闭此帖子并链接到它。

NumberFormat.parse(String)
的行为正是:

从给定字符串的开头解析文本以生成数字该方法不能使用给定字符串的整个文本。

(增加重点)

你问:

除了编写自己的包装器类(对多个小数点分隔符等进行额外检查)之外,还有什么方法可以使用
NumberFormat
来实现我所需/预期的行为

您不能提供一种格式,该格式将使
NumberFormat.parse()
为输入抛出一个异常,该异常只包含一个可以根据该格式解析的初始子字符串。但是,您可以使用
NumberFormat.parse(String,ParsePosition)
来确定是否对整个输入进行了解析,因为parse position参数不仅用于指示方法从何处开始,还用于指示方法停止的位置。这比实现特定于格式的额外检查要好得多。例如:

ParsePosition position = new ParsePosition(0);
Number result = format.parse(input, position);

if (position.getIndex() != input.length()) {
    throw new MyException();
}
此外,你还写道:

但这并没有告诉我为什么方法会这样

这样做是因为有时解析输入的初始部分正是您想要做的。如图所示,您可以在更轻松的解析基础上构建更严格的解析,但反过来要做到这一点要困难得多。

“为什么”是因为他们就是这样写的(°o)/”。如果行为不适合您的需要,您需要将其包装或使用不同的解析机制。