{0}과 {0,number,integer}의 차이점은 무엇입니까?
-
12-12-2019 - |
문제
나는 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)