BigDecimal 语言环境特定解析 - Wicket 的 BigDecimalConverter 和 java.math.BigDecimal 之间不一致
当从字符串中解析带有小数分隔符的数字时,Wicket 的 BigDecimalConverter 的行为与 BigDecimal 的 (String val) 构造函数不同。
让我们尝试使用美国语言环境解析以逗号作为小数分隔符的数字。 (顺便说一句,我使用的是 Wicket 1.4.14。)
new BigDecimalConverter().convertToObject("1,3", Locale.US)
返回 13
,
但
Locale.setDefault(Locale.US);
new BigDecimal("1,3")
抛出 NumberFormatException
。
在这种情况下,为什么 BigDecimalConverter 的行为与 BigDecimal 不同?数字“1,3”对于美国语言环境没有意义。
When it comes to parsing numbers with decimal separators from string, Wicket's BigDecimalConverter behaves differently than BigDecimal's (String val) constructor.
Let's try to parse a number with comma as the decimal separator using US locale. (I'm using Wicket 1.4.14 BTW.)
new BigDecimalConverter().convertToObject("1,3", Locale.US)
returns 13
,
but
Locale.setDefault(Locale.US);
new BigDecimal("1,3")
throws NumberFormatException
.
Why doesn't BigDecimalConverter behave the same way as BigDecimal in this case? The number "1,3" doesn't make sense for the US locale.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
BigDecimal 类在输入上实现自己的验证算法,该算法会抛出 NumberFormatException。
BigDecimalConverter
将1,3
解析为13
的原因是它在幕后使用原始DecimalFormat
。在AbstractNumberConverter.parse()
,getNumberFormat(locale)
和parse()
方法组合归结为以下代码片段,将 Wicket 排除在等式之外:UPDATE
DecimalFormat
忽略,
字符的原因是它在美国语言环境的DecimalFormatSymbols
中被定义为分组分隔符。这是允许的,并且是合法的,就像在
1,300.5
中一样。如果您想避免将
1,3
转换为13
,并抛出无效的格式转换异常,您可以重写BigDecimalConverter.getNumberFormat(Locale)
为了将DecimalFormat
修改为不使用分组,请使用不同的分组符号,或使用更具限制性的模式。例如:注意:谨慎使用上面的示例,为转换器创建一个类,这样它就不会在每次调用
getConverter()
时实例化,并且不要修改NumberFormat
实例BigDecimalConverter.getNumberFormat()
返回,它可能是一个全局共享实例。只是补充一下,这是忽略
,
字符作为组分隔符的确切代码:DecimalFormat.subparse()
第 1522 行分支。输入1,3
时,逗号将被忽略,为isGroupingUsed()
true。The
BigDecimal
class implements its own validation algorithm on the input, which is throwing theNumberFormatException
.The reason why
BigDecimalConverter
is parsing1,3
as13
is that it is using a rawDecimalFormat
behind the scenes. InAbstractNumberConverter.parse()
, thegetNumberFormat(locale)
andparse()
methods combination boils down to the following snippet, that takes Wicket out of the equation:UPDATE
The reason why
DecimalFormat
is ignoring the,
character is because it is defined as the grouping separator in theDecimalFormatSymbols
for the US locale.It is permitted, and legal as it would be in
1,300.5
.In case you want to avoid converting
1,3
to13
, and throwing a invalid format conversion exception, you could overrideBigDecimalConverter.getNumberFormat(Locale)
in order to modify theDecimalFormat
to not use grouping, use a different grouping symbol, or use a more restrictive pattern. For instance:Note: Use the above example with caution, create a class for the Converter so it doesn't get instantiated at each call of
getConverter()
and don't modify theNumberFormat
instanceBigDecimalConverter.getNumberFormat()
returns, it might be a global shared instance.Just to add, this is the exact piece of code that's ignoring the
,
character for being a group separator:DecimalFormat.subparse()
branch in line 1522. With input of1,3
, the comma is ignored, beingisGroupingUsed()
true.