pra*_*pes 1 java wicket bigdecimal
当使用字符串中的十进制分隔符解析数字时,Wicket的BigDecimalConverter的行为与BigDecimal的(String val)构造函数不同.
让我们尝试用逗号作为使用美国语言环境的小数分隔符来解析数字.(我正在使用Wicket 1.4.14 BTW.)
new BigDecimalConverter().convertToObject("1,3", Locale.US)
回来13,
但
Locale.setDefault(Locale.US);
new BigDecimal("1,3")
Run Code Online (Sandbox Code Playgroud)
抛出NumberFormatException.
在这种情况下,为什么BigDecimalConverter的行为与BigDecimal不同?数字"1,3"对于美国语言环境没有意义.
在BigDecimal类实现输入,这是抛出了自己的验证算法NumberFormatException.
为什么原因BigDecimalConverter被解析1,3为13的是,它使用的是原始DecimalFormat的幕后.在AbstractNumberConverter.parse(),getNumberFormat(locale)和parse()方法组合归结为以下片段,将Wicket从等式中取出:
NumberFormat format = NumberFormat.getInstance(Locale.US);
format.setParseBigDecimal(true);
BigDecimal bd = format.parseObject("1,3");
System.out.println(bd.toString()); // Prints 13 !
Run Code Online (Sandbox Code Playgroud)
更新DecimalFormat忽略该,字符
的原因是因为它被定义为DecimalFormatSymbols美国语言环境中的分组分隔符.它是允许的,并且是合法的1,300.5.
如果你想避免转换1,3到13,并抛出一个无效的格式转换的异常,你可以重写BigDecimalConverter.getNumberFormat(Locale),以修改DecimalFormat不使用分组,使用不同的分组符号,或者使用更严格的模式.例如:
TextField<BigDecimal> text = new TextField<BigDecimal>(id, model){
@Override
public IConverter getConverter(Class<?> type) {
return new BigDecimalConverter() {
@Override
public NumberFormat getNumberFormat(Locale locale) {
NumberFormat format = super.getNumberFormat(locale);
format.setGroupingUsed(false);
return format;
}
};
}
};
text.setType(BigDecimal.class);
Run Code Online (Sandbox Code Playgroud)
注意:请谨慎使用上面的示例,为Converter创建一个类,这样它在每次调用时都不会被实例化,getConverter()也不会修改NumberFormat实例BigDecimalConverter.getNumberFormat()返回,它可能是一个全局共享实例.
只是要添加,这是忽略,作为组分隔符的字符的确切代码:DecimalFormat.subparse()第1522行中的分支.输入后1,3,逗号被忽略,为isGroupingUsed()真.