문제

나는 Java에 대해 더 많이 이해하려고 노력하고 있습니다. 메시지 형식 유틸리티, 코드베이스 및 다른 곳의 예제에서 두 가지를 모두 볼 수 있습니다. {0} 그리고 {0,number,integer} 숫자에 사용되지만 둘 중 어느 것이 더 바람직한지는 잘 모르겠습니다.

차이점을 인쇄하는 빠른 테스트:

import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Locale;

public class MessageFormatTest
{
    public static void main(String[] args){
        MessageFormat simpleChoiceTest = new MessageFormat("{0}");
        MessageFormat explicitChoiceTest = new MessageFormat("{0,number,integer}");
        int[] set = new int[]{0,1,4,5,6,10,10000,24345};
        Locale[] locs = new Locale[]{Locale.US,Locale.UK,Locale.FRANCE,Locale.GERMANY};
        for(Locale loc : locs){
            simpleChoiceTest.setLocale(loc);
            explicitChoiceTest.setLocale(loc);
            for(int i : set){
                String simple = simpleChoiceTest.format(new Object[]{i});
                String explicit = explicitChoiceTest.format(new Object[]{i});
                if(!simple.equals(explicit)){
                    System.out.println(loc+" - "+i+":\t"+simple+
                        "\t"+NumberFormat.getInstance(loc).format(i));
                    System.out.println(loc+" - "+i+":\t"+explicit+
                        "\t"+NumberFormat.getIntegerInstance(loc).format(i));
                }
            }
        }
    }
}

출력:

fr_FR - 10000:  10 000  10 000
fr_FR - 10000:  10,000  10 000
fr_FR - 24345:  24 345  24 345
fr_FR - 24345:  24,345  24 345
de_DE - 10000:  10.000  10.000
de_DE - 10000:  10,000  10.000
de_DE - 24345:  24.345  24.345
de_DE - 24345:  24,345  24.345

그것은 나를 놀라게 했습니다. 만약 내가 무엇이든 기대했다면 {0} 그 번호에 아무 짓도 하지 말라고, 그리고 {0,number,integer} 제대로 현지화하려면.대신 둘 다 지역화되지만 명시적인 형식은 항상 en_US 지역화를 사용하는 것 같습니다.

링크된 문서에 따르면, {0} 통과된다 NumberFormat.getInstance(getLocale()) 명시적인 형식이 사용되는 동안 NumberFormat.getIntegerInstance(getLocale()).그러나 이를 직접 호출하면(출력의 마지막 열) 둘 다 동일해 보이고 둘 다 올바르게 현지화됩니다.

내가 여기서 무엇을 놓치고 있는 걸까요?

도움이 되었습니까?

해결책

당신 말이 맞아요."MessageFormat("{0,number,integer}")"를 사용하면 포맷터는 초기화 시 기본 로케일(en_US)을 사용하고 아래 코드가 실행되면서 숫자는 기본 로케일(en_US)에서 정수 형식을 사용하도록 표시됩니다. 초기화 시간 자체 동안.

// this method is internally called at the time of initialization
MessageFormat.makeFormat()
// line below uses default locale if locale is not
// supplied at initialization (constructor argument) 
newFormat = NumberFormat.getIntegerInstance(locale);

나중에 로케일을 설정하므로 숫자에 할당된 형식 패턴에는 영향이 없습니다.원하는 로캘을 숫자 형식으로 사용하려면 초기화 자체 시 로캘 인수를 사용하세요.아래에:

MessageFormat test = new MessageFormat("{0,number,integer}", Locale.FRANCE);

다른 팁

제 생각에는 이것은 Java 버그(인터페이스가 잘못됨)이거나 문서 문제입니다.이를 수정하려면 Oracle에서 새 문제를 열어야 합니다.

Yogendra Singh은 MessageFormat 생성자가 생성될 때 포맷터(DecimalFormat)의 인스턴스가 생성된다고 말했습니다.

MessageFormat simpleChoiceTest = new MessageFormat("{0}");
System.out.println(simpleChoiceTest.getFormatsByArgumentIndex()[0]);
//Prints null
MessageFormat explicitChoiceTest = new MessageFormat("{0,number,currency}");
System.out.println(explicitChoiceTest.getFormatsByArgumentIndex()[0]);
//Prints java.text.DecimalFormat@67500

MessageFormat.setLocale이 호출되면 내부 포맷터의 로케일이 변경되지 않습니다.

최소한 문서는 이 문제를 반영하도록 변경되어야 합니다.

그것은 내 자바 버전입니다.Java 버전 "1.7.0_07"Java (TM) SE 런타임 환경 (빌드 1.7.0_07-B11)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top