Класс 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 !
UPDATE
Причина, по которой 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);
Примечание : используйте приведенный выше пример с осторожностью, создайте класс для Converter, чтобы он не создавался при каждом вызове getConverter()
, и не изменяйте экземпляр NumberFormat
BigDecimalConverter.getNumberFormat()
возвращает, это может быть глобальный общий экземпляр.
Просто добавьте, это точный фрагмент кода, который игнорирует символ ,
, являющийся разделителем групп: DecimalFormat.subparse()
ветвь в строке 1522 . При вводе 1,3
запятая игнорируется, а isGroupingUsed()
true.