BigDecimal特定于区域设置的解析-Wicket和#x27;s BigDecimalConverter和java.math.BigDecimal

BigDecimal特定于区域设置的解析-Wicket和#x27;s BigDecimalConverter和java.math.BigDecimal,java,wicket,bigdecimal,Java,Wicket,Bigdecimal,当涉及到用十进制分隔符从字符串解析数字时,Wicket的BigDecimalConverter的行为与BigDecimal的(string val)构造函数不同 让我们尝试使用US语言环境解析一个以逗号作为小数分隔符的数字。(我正在使用Wicket 1.4.14 BTW) new BigDecimalConverter().convertToObject(“1,3”,Locale.US) 返回13 但是 抛出NumberFormatException 在这种情况下,为什么BigDecim

当涉及到用十进制分隔符从字符串解析数字时,Wicket的BigDecimalConverter的行为与BigDecimal的(string val)构造函数不同

让我们尝试使用US语言环境解析一个以逗号作为小数分隔符的数字。(我正在使用Wicket 1.4.14 BTW)


new BigDecimalConverter().convertToObject(“1,3”,Locale.US)

返回
13


但是


抛出
NumberFormatException



在这种情况下,为什么BigDecimalConverter的行为与BigDecimal不一样?数字“1,3”在美国地区没有意义。

BigDecimal类在输入上实现自己的验证算法,这会抛出
NumberFormatException

BigDecimalConverter
1,3
解析为
13
的原因是它在幕后使用原始的
DecimalFormat
。在中,和方法的组合归结为以下片段,将Wicket从等式中去掉:

NumberFormat format = NumberFormat.getInstance(Locale.US);
format.setParseBigDecimal(true);
BigDecimal bd = format.parseObject("1,3");
System.out.println(bd.toString()); // Prints 13 !
更新
DecimalFormat
之所以忽略
字符,是因为它在美国地区的
DecimalFormatSymbols
中被定义为分组分隔符。 在
1300.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);
TextField text=新的TextField(id,型号){
@凌驾
公共IConverter getConverter(类类型){
返回新的BigDecimalConverter(){
@凌驾
公共数字格式getNumberFormat(区域设置){
NumberFormat format=super.getNumberFormat(区域设置);
format.setGroupingUsed(false);
返回格式;
}
};
}
};
setType(BigDecimal.class);
注意:谨慎使用上述示例,为转换器创建一个类,这样它就不会在每次调用
getConverter()
时被实例化,也不会修改
NumberFormat
实例
BigDecimalConverter.getNumberFormat()
返回,它可能是一个全局共享实例


要补充的是,这段代码忽略了作为组分隔符的
字符:。输入
1,3
,逗号被忽略,即
isGroupingUsed()
true

BigDecimal类对输入实现自己的验证算法,该算法抛出
NumberFormatException

BigDecimalConverter
1,3
解析为
13
的原因是它在幕后使用原始的
DecimalFormat
。在中,和方法的组合归结为以下片段,将Wicket从等式中去掉:

NumberFormat format = NumberFormat.getInstance(Locale.US);
format.setParseBigDecimal(true);
BigDecimal bd = format.parseObject("1,3");
System.out.println(bd.toString()); // Prints 13 !
更新
DecimalFormat
之所以忽略
字符,是因为它在美国地区的
DecimalFormatSymbols
中被定义为分组分隔符。 在
1300.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);
TextField text=新的TextField(id,型号){
@凌驾
公共IConverter getConverter(类类型){
返回新的BigDecimalConverter(){
@凌驾
公共数字格式getNumberFormat(区域设置){
NumberFormat format=super.getNumberFormat(区域设置);
format.setGroupingUsed(false);
返回格式;
}
};
}
};
setType(BigDecimal.class);
注意:谨慎使用上述示例,为转换器创建一个类,这样它就不会在每次调用
getConverter()
时被实例化,也不会修改
NumberFormat
实例
BigDecimalConverter.getNumberFormat()
返回,它可能是一个全局共享实例


要补充的是,这段代码忽略了作为组分隔符的
字符:。输入
1,3
,逗号被忽略,即
isGroupingUsed()
true

@Chris不会忽略
Locale
。wiki示例中的代码不是转换器的实际代码。它返回
13
的原因似乎与
DecimalFormat
有关,这是我一天内第二次详尽回答我的问题。非常感谢,哈维@Chris不会忽略
Locale
。wiki示例中的代码不是转换器的实际代码。它返回
13
的原因似乎与
DecimalFormat
有关,这是我一天内第二次详尽回答我的问题。非常感谢,哈维!