2012-01-06 11 views
15

La seguente non si comporta sempre come ci si aspetterebbe:test se un valore BigDecimal è pari a zero in un'espressione JSP EL

<c:if test="${someBigDecimal == 0}"> 

Se someBigDecimal ha un valore pari a 0, ma ha una scala diverso da 0, il L'operazione == restituisce false. Ovvero, restituisce true quando someBigDecimal è nuovo BigDecimal ("0"), ma false quando someBigDecimal è nuovo BigDecimal ("0.00").

Ciò è dovuto al JSP 2.0, 2.1, e 2.2 specifiche, in cui si afferma:

Per <,>, < =,> =:

Se A o B è BigDecimal, costringere entrambi A e B a BigDecimal e utilizzano il valore restituito da A.compareTo (B).

Per ==, =:

Se A o B è BigDecimal, costringere sia A che B per BigDecimal e poi:

  • Se operatore ==, ritornare A .equals (B)
  • Se operatore! =, ritorno! A.equals (B)

Ciò significa che gli operatori == e != generano una chiamata al metodo .equals(), che confronta non solo i valori, ma anche la scala dei BigDecimals. Gli altri operatori di confronto generano una chiamata al metodo .compareTo(), che confronta solo i valori.

Naturalmente, il seguente dovrebbe funzionare:

<c:if test="${not ((someBigDecimal < 0) or (someBigDecimal > 0))}"> 

Ma questo è piuttosto brutto, c'è un modo migliore per fare questo?

+3

Qual è la tua domanda? – kcdragon

+0

@ user617090 Basta chiedersi quale sia il modo migliore per gestire questo. Ho modificato la domanda per renderla più chiara. –

+0

Cosa succede se usi '== 0.0'? –

risposta

10

In JSP 2.2 EL e sopra di questa espressione restituirà true:

${someBigDecimal.unscaledValue() == 0} 

Ciò eviterà qualsiasi perdita di precisione ma presuppone che someBigDecimal sia sempre di tipo BigDecimal.

Un custom EL function è probabilmente l'approccio migliore per le vecchie versioni di EL:

${fn:isZero(someBigDecimal)} 

Il nocciolo del problema è che questo codice Java restituisce false perché ZERO ha una scale di 0 ed il nuovo BigDecimal ha una scala diversa da zero:

BigDecimal.ZERO.setScale(3).equals(BigDecimal.ZERO) 
+0

Grazie per la risposta. Per ora siamo bloccati con JSP 2.1. Avevamo pensato a una funzione personalizzata, ma speravo di evitarlo. Sono d'accordo, tuttavia, che è l'approccio migliore. –

2

Con l'ultima versione di EL (supportato da Tomcat 7, per esempio), si può provare:

<c:if test="${someBigDecimal.doubleValue() == 0}"> 
2
<c:if test="${someBigDecimal.compareTo(BigDecimal.ZERO) == 0}"> 
+0

Penso che questa sarebbe la strada da percorrere se fossimo sulla specifica JSP 2.2. La mia domanda era limitata a confrontare un BigDecimal con uno zero letterale, ma questo avrebbe funzionato anche per confrontare due valori BigDecimal. –

2
<c:if test="${someBigDecimal eq 0}"> 
+1

Stai dicendo che 'eq' si comporta diversamente da' == '? Perché capisco che 'eq' è solo un alias per' == '. –

+0

Sì, sono diversi. Proprio come la relazione tra "uguale()" e "==" in java. – peakmuma

+1

Siamo spiacenti, ma 'eq' è solo un alias per' == '; [non sono diversi] (http://stackoverflow.com/questions/2087721/difference-between-eq-and-in-jsp). –

0

Si può provare la funzione signum:

<c:if test="#{someBigDecimal.signum() == 0}">