2011-11-04 1 views
1

string에서 소수 구분 기호가있는 숫자를 구문 분석 할 때 Wicket의 BigDecimalConverter는 BigDecimal (String val) 생성자와 다르게 동작합니다.BigDecimal 로캘 별 구문 분석 - Wicket의 BigDecimalConverter와 java.math.BigDecimal 간의 불일치

미국 로캘을 사용하여 소수점 구분 기호로 쉼표로 숫자를 분석해 보겠습니다. (내가 BTW 개찰구 1.4.14을 사용하고 있습니다.)


new BigDecimalConverter().convertToObject("1,3", Locale.US)
반환 13,


하지만


Locale.setDefault(Locale.US); 
new BigDecimal("1,3") 

NumberFormatException가 발생합니다.


왜 BigDecimalConverter는이 경우 BigDecimal과 같은 방식으로 작동하지 않습니까? 숫자 "1,3"은 미국 로켈에 대해 이해가되지 않습니다.

답변

6

BigDecimal 클래스는 NumberFormatException을 던지는 입력에 대해 고유 한 유효성 검사 알고리즘을 구현합니다.

BigDecimalConverter131,3을 분석하는 이유는 보이지 않는 원시 DecimalFormat을 사용하고 있다는 점이다. AbstractNumberConverter.parse()에서 getNumberFormat(locale)parse() 방법의 조합 식 중 개찰을 얻어 다음 코드로 귀결

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입니다.

당신이 131,3을 변환하고, 잘못된 형식 변환 예외가 발생하지 않도록하려는 경우

, 당신은 그룹을 사용하여 다른 그룹의 기호를 사용하거나 더 제한적인 패턴을 사용하지 않도록 DecimalFormat을 수정하기 위해 BigDecimalConverter.getNumberFormat(Locale)을 무시할 수 .

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); 

: 예를 들어이 getConverter()의 각 호출에 인스턴스화되지 않고 NumberFormat 예를 BigDecimalConverter.getNumberFormat() 반환을 수정하지 않도록 컨버터의 클래스를 만들고,주의 위의 예를 사용하여, 글로벌 공유 인스턴스 일 수 있습니다.

그냥 추가하면 그룹 구분 기호 인 , 문자를 무시하는 코드와 정확히 일치합니다 : DecimalFormat.subparse() branch in line 1522. 1,3 입력시 쉼표는 무시되고 isGroupingUsed()이 참입니다.

+1

@Chris ['BigDecimalConverter'] (http://grepcode.com/file/repo1.maven.org/maven2/org.apache.wicket/wicket/1.4.17/org/apache/wicket/util/convert/변환기/BigDecimalConverter.java # 44) *는'Locale'을 무시하지 않습니다. 위키 예제의 코드는 변환기의 실제 코드가 아닙니다. 그것이 '13'을 반환하는 이유는 DecimalFormat에만 해당됩니다. –

+1

그것은 내 질문에 대한 두 번째 철저한 대답이었습니다. 고마워, 사비! – prasopes