java - NumberFormat 不会因 2 个小数点分隔符而崩溃

标签 java number-formatting

我对 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/

相关文章:

java - RAM <4GB 的 64 位虚拟机上 Java 中的对象 header 大小

java - Android Spinner 选定项目操作

java - 带有嵌套 pojo 的 Firebase Java setter 和 getter

java - 通过 https 和防火墙的 SOAP Spring 客户端请求

java - 在 Android Studio 的 EditText 中添加逗号作为数字的千位分隔符?

c# - 为什么 Convert.ToDecimal(3.1922) 显示为 31922?

java - 如何正确实现定时器?

javascript - 带有 accounting.js 格式的输入框不允许我输入小数

c++ - 你如何设置 cout 语言环境来插入逗号作为千位分隔符?

c# - excel 数字格式