What is the difference between {0} and {0, number, integer}

I'm trying to understand more about Java MessageFormat utilities, and in the examples on our code base and elsewhere, I see how {0} and {0,number,integer} are used for numbers, but I'm not sure which one is preferable.

Quick print differences test:

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

Outputs:

 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 

What surprised me if I expected {0} do nothing with the number, and for {0,number,integer} to localize it correctly. Instead, both become localized, but it seems that the explicit form always uses the en_US localization.

According to related documentation, {0} gets the value through NumberFormat.getInstance(getLocale()) , while the explicit form uses NumberFormat.getIntegerInstance(getLocale()) . However, when I call them directly (the last column in the output), both seem to be the same and both are localized correctly.

What am I missing here?

+4
source share
2 answers

You're right. When you use "MessageFormat" ("{0, number, integer}"), formatter uses the standard locale (en_US) during initialization, and numbers are marked to use the Integer format in the default locale (en_US) as the code runs lower during initialization time.

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

Since you set the locale subsequently, the format template assigned to the numbers is not affected. If you want to use the locale of desire in a format for numbers, use the locale argument during initialization itself, for example. below:

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

In my opinion, this is a Java error (the interface is incorrect) or a problem with the documentation. You must open a new problem in Oracle to fix this.

Like Yogendra Singh, said that a formatting instance (DecimalFormat) is created when the MessageFormat constructor.

 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 

When MessageFormat.setLocale is called, it does not change the locale of its internal formatters.

At the very least, the documentation should be modified to reflect this problem.

This is my java version: java version "1.7.0_07" Java (TM) SE Runtime Environment (build 1.7.0_07-b11)

0
source

Source: https://habr.com/ru/post/1437443/


All Articles