¿Cuál es la diferencia entre {0} y {0,número,entero}
-
12-12-2019 - |
Pregunta
Estoy tratando de entender más sobre Java. Formato de mensaje utilidades, y en ejemplos en nuestro código base y en otros lugares veo ambos {0}
y {0,number,integer}
se usa para números, pero no estoy seguro de cuál es preferible, si es que es preferible.
Una prueba rápida imprimiendo las diferencias:
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));
}
}
}
}
}
Salidas:
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
Lo que me sorprendió, en todo caso hubiera esperado el {0}
para no hacerle nada al número, y para {0,number,integer}
para localizarlo correctamente.En cambio, ambos se localizan, pero parece que la forma explícita siempre usa la localización en_US.
Según la documentación vinculada, {0}
se pone a través NumberFormat.getInstance(getLocale())
mientras que la forma explícita usa NumberFormat.getIntegerInstance(getLocale())
.Sin embargo, cuando los llamo directamente (la última columna del resultado), ambos parecen idénticos y ambos se localizan correctamente.
¿Que me estoy perdiendo aqui?
Solución
Tienes razón.Cuando usa "MessageFormat("{0,number,integer}")", el formateador usa la configuración regional predeterminada (en_US) en el momento de la inicialización y los números están marcados para usar el formato entero en la configuración regional predeterminada (en_US) mientras se ejecuta el código siguiente durante el propio tiempo de inicialización.
// 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);
Dado que usted configura la configuración regional después, no hay ningún impacto en el patrón de formato asignado a los números.Si desea utilizar la configuración regional deseada en el formato de números, utilice el argumento de configuración regional en el momento de la inicialización, p.abajo:
MessageFormat test = new MessageFormat("{0,number,integer}", Locale.FRANCE);
Otros consejos
En mi opinión, esto es un error de Java (la interfaz es incorrecta) o un problema de documentación.Debería abrir una nueva edición en Oracle para corregirlo.
Como dijo Yogendra Singh, la instancia del formateador (DecimalFormat) se crea cuando el constructor 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
Cuando se llama a MessageFormat.setLocale, no cambia la configuración regional de sus formateadores internos.
Al menos la documentación debería cambiarse para reflejar este problema.
Esa es mi versión de java:Versión de Java "1.7.0_07" Java (TM) SE Runtime Entorno (Build 1.7.0_07-B11)