Qual è la differenza tra {0} e {0, number, integer}
-
12-12-2019 - |
Domanda
Sto cercando di capire di più su Java MessageFormat utilità, e negli esempi nella nostra base di codice e altrove vedo entrambi {0}
e {0,number,integer}
essere usato per i numeri, ma non sono sicuro di quale, se uno dei due, sia preferibile.
Un test rapido stampa le differenze:
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));
}
}
}
}
}
Uscita:
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
Che mi ha sorpreso, semmai mi sarei aspettato il {0}
per non fare nulla al numero, e per {0,number,integer}
per localizzarlo correttamente.Invece, entrambi vengono localizzati, ma sembra che la forma esplicita usi sempre la localizzazione en_US.
Secondo la documentazione collegata, {0}
viene messo attraverso NumberFormat.getInstance(getLocale())
mentre mentre la forma esplicita utilizza NumberFormat.getIntegerInstance(getLocale())
.Eppure quando li chiamo direttamente (l'ultima colonna nell'output) entrambi sembrano identici, ed entrambi si localizzano correttamente.
Cosa mi manca qui?
Soluzione
Hai ragione.Quando si utilizza " MessageFormat ("{0,number,integer}")", formatter utilizza le impostazioni locali predefinite(en_US) al momento dell'inizializzazione e i numeri sono contrassegnati per utilizzare il formato Intero nelle impostazioni locali predefinite (en_US) poiché il codice sottostante viene eseguito durante il tempo di inizializzazione stesso.
// 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);
Poiché si impostano le impostazioni locali in seguito, non vi è alcun impatto sul modello di formato assegnato ai numeri.Se si desidera utilizzare la locale desire nel formato per i numeri, utilizzare l'argomento locale al momento dell'inizializzazione stessa, ad es.sotto:
MessageFormat test = new MessageFormat("{0,number,integer}", Locale.FRANCE);
Altri suggerimenti
A mio parere, questo è un bug Java (l'interfaccia è sbagliata) o un problema di documentazione.Dovresti aprire un nuovo problema su Oracle per correggerlo.
Come Yogendra Singh, ha detto che l'istanza del formattatore (DecimalFormat) viene creato quando il costruttore 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
Quando il MessageFormat.setLocale è chiamato non cambia le impostazioni locali dei suoi formattatori interni.
Almeno la documentazione dovrebbe essere modificata per riflettere questo problema.
Questa è la mia versione java:versione java "1.7.0_07" Ambiente di runtime Java(TM) SE (build 1.7.0_07-b11)