2016-03-22 10 views
11

Perché java.text.DecimalFormat valutare i seguenti risultati:Perché DecimalFormat ". #" E "0. #" hanno risultati diversi su 23.0?

new DecimalFormat("0.#").format(23.0)  // result: "23" 

new DecimalFormat(".#").format(23.0)   // result: "23.0" 

mi sarei aspettato che il risultato sia 23 in entrambi i casi, in quanto carattere speciale # omette zeri. In che modo il personaggio speciale principale 0 influisce sulla parte della frazione? (Cercato di far corrispondere/capire con il BNF dato in javadoc, ma non è riuscito a farlo.)

+0

Mi chiedo se "". # "' È un formato valido e se non dovrebbe essere '#. #', Che risulta anche in '23'. – Tom

+0

@Tom: DecimalFormat (". 0") funziona anche. Non ho visto nulla nella javadoc che proibisca cose come ". #". – MGn

+0

* "Non ho visto nulla nella javadoc che proibisca cose come". # "" * Nemmeno io, ma questo non significa che il codice possa gestirlo correttamente. Anche che 'DecimalFormat (". 0 ")' funziona può essere una coincidenza quando '. #' O '.0' non sono validi e il" fallback "stampa solo il numero, poiché risulterebbe nella stessa stringa (' "23.0" '). Ma di nuovo, è solo una supposizione. – Tom

risposta

7

Il secondo formato sembra non valido secondo lo JavaDoc, ma in qualche modo analizza senza errori comunque.

Pattern: 
     PositivePattern 
     PositivePattern ; NegativePattern 
PositivePattern: 
     Prefixopt Number Suffixopt 
NegativePattern: 
     Prefixopt Number Suffixopt 
Prefix: 
     any Unicode characters except \uFFFE, \uFFFF, and special characters 
Suffix: 
     any Unicode characters except \uFFFE, \uFFFF, and special characters 
Number: 
     Integer Exponentopt 
     Integer . Fraction Exponentopt 
Integer: 
     MinimumInteger 
     # 
     # Integer 
     # , Integer 
MinimumInteger: 
     0 
     0 MinimumInteger 
     0 , MinimumInteger 
Fraction: 
     MinimumFractionopt OptionalFractionopt 
MinimumFraction: 
     0 MinimumFractionopt 
OptionalFraction: 
     # OptionalFractionopt 
Exponent: 
     E MinimumExponent 
MinimumExponent: 
     0 MinimumExponentopt 

In questo caso mi aspetto il comportamento del formattatore da undefined. Cioè, può produrre qualsiasi cosa vecchia e non possiamo fare affidamento sul fatto che sia coerente o significativo in alcun modo. Quindi, non so perché stai ottenendo il 23.0, ma puoi presumere che sia una sciocchezza che dovresti evitare nel tuo codice.

Aggiornamento: Ho appena eseguito un debugger tramite la libreria DecimalFormat di Java 7. Il codice non solo dice esplicitamente che '. #' È permesso, c'è un commento in là (java.text.DecimalFormat: 2582-2593) che dice che è permesso e un'implementazione che lo consente (riga 2597). Questo sembra essere in violazione del BNF documentato per il modello.

Dato che non si tratta di un comportamento documentato, non si dovrebbe fare affidamento su di esso in quanto è soggetto a modifiche tra versioni di Java o persino implementazioni di libreria.

3

Il seguente commento di origine spiega la gestione piuttosto non intuitiva di ".#". Linee 3383-3385 ​​nel mio DecimalFormat.java di file (JDK 8) hanno il seguente commento:

// Handle patterns with no '0' pattern character. These patterns 
// are legal, but must be interpreted. "##.###" -> "#0.###". 
// ".###" -> ".0##". 

Sembra come gli sviluppatori hanno scelto di interpretare ".#" come ".0##", invece di quello che vi aspettavate ("0.#").

+0

Stavo solo guardando il codice sorgente di DecimalFormat e l'ho visto. – callyalater

+0

Lo avevo già documentato nella mia risposta, ma ho numeri di linea diversi per te. Mi chiedo che cosa causa questa discrepanza? Non hai menzionato la versione di java a cui stai facendo riferimento qui. Puoi aggiungere questo per chiarezza in quanto potrebbe essere responsabile? –

+0

Sto usando JDK 8, questa è la differenza. – MicSim