В чем разница между {0} и {0,число, целое число}
-
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,число,целое число}")", средство форматирования использует языковой стандарт по умолчанию(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);
Поскольку впоследствии вы устанавливаете языковой стандарт, это никак не влияет на шаблон формата, присвоенный числам.Если вы хотите использовать желаемый языковой стандарт в формате для чисел, пожалуйста, используйте аргумент locale во время самой инициализации, напримерниже:
MessageFormat test = new MessageFormat("{0,number,integer}", Locale.FRANCE);
Другие советы
На мой взгляд, это ошибка Java (неправильный интерфейс) или проблема с документацией.Вам следует открыть новую проблему в Oracle, чтобы исправить это.
Как сказал Йогендра Сингх, экземпляр форматировщика (DecimalFormat) создается при использовании конструктора MessageFormat.
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:версия java "1.7.0_07" Среда выполнения Java(TM) SE (сборка 1.7.0_07-b11)