我对 NumberFormat
的行为有疑问:
当我想将格式化的String
转换/解析为Number
时,我想使用NumberFormat
,因为它为我提供了具有千位和小数分隔符的良好预设。此外,如果提供的 String
不是有效的 Number
,我希望它崩溃。
一个例子:
// 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(String s)
来实现此附加行为:
// crashes with java.lang.NumberFormatException: multiple points
double number2WithError = Double.parseDouble(testInput2.replace(",", "."));
除了编写自己的包装类来执行一些额外的检查(例如,多个小数分隔符?
<小时/>此外,我知道 NumberFormat
使用的 parse(String source)
方法的 JavaDoc 说:
Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.
See the {@link #parse(String, ParsePosition)} method for more information on number parsing.
和解析(字符串源,ParsePosition parsePosition)
:
Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, Long.MAX_VALUE] and with no decimals), otherwise a Double. If IntegerOnly is set, will stop at a decimal point (or equivalent; e.g., for rational numbers "1 2/3", will stop after the 1). Does not throw an exception; if no object can be parsed, index is unchanged!
这并没有告诉我为什么该方法会这样运行。我从这些中得到的是,他们只能解析 String 的一部分(他们显然在这里所做的),并且可能只是从开头(开始位置)开始解析,直到找到他们无法处理的东西与。
<小时/>我没有找到涉及此问题的现有问题,因此如果已有问题,请随时关闭这篇文章并提供指向它的链接。
最佳答案
NumberFormat.parse(String)
的行为完全 as documented :
Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.
(已添加强调)
你问:
Is there a way I can use
NumberFormat
to have my required/expected behavior besides writing my own wrapper class that does some additional checks on e.g. multiple decimal separators?
您无法提供一种格式,该格式会使 NumberFormat.parse()
对于仅包含可根据该格式进行解析的初始子字符串的输入抛出异常。但是,您可以使用NumberFormat.parse(String, ParsePosition)
来确定是否解析了整个输入,因为解析位置参数不仅用于指示方法从哪里开始,还可以让方法说出它在哪里停止。这比实现特定于格式的额外检查要好得多。示例:
ParsePosition position = new ParsePosition(0);
Number result = format.parse(input, position);
if (position.getIndex() != input.length()) {
throw new MyException();
}
此外,您还写道:
This doesn't tell me though why the method behaves this way.
它的行为方式是因为有时解析输入的初始部分正是您想要做的。您可以在更宽松的解析之上构建更严格的解析,如图所示,但反之则要困难得多。
关于java - NumberFormat 不会因 2 个小数点分隔符而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42584646/