2011-10-25 10 views
15

trovo cose come questa piuttosto fastidioso e brutto in equals metodi:Come prevenire assegno nulla è uguale a prima

if (field == null) 
{ 
    if (other.field != null) 
     return false; 
} 
else if (! field.equals(other.field)) 
    return false; 

in C# ho potuto ho fatto questo:

if(! Object.Equals(field, other.field)) 
    return false; 

C'è qualcosa di simile in Java, o qual è il modo preferito di fare questo tipo se qualcosa?

+1

Penso che troverete questa discussione utile: http://stackoverflow.com/questions/271526/how-to-avoid-null-statements-in-java – hovanessyan

+0

Interessante, certo. Utile ... personalmente per lo più sollevo solo altre domande: p – Svish

risposta

23

Utilizzare commons-lang: codice

org.apache.commons.lang.ObjectUtils.equals(Object object1, Object object2) 

Fonte:

public static boolean equals(Object object1, Object object2) { 
    if (object1 == object2) { 
     return true; 
    } 
    if ((object1 == null) || (object2 == null)) { 
     return false; 
    } 
    return object1.equals(object2); 
} 

Da Apache

http://commons.apache.org/lang/

che è circa equivalente a quello che si fa in C#

+0

E se impor che il metodo statico (importazione org.apache.commons.lang.ObjectUtils.equals statiche;) allora si può scrivere semplicemente 'uguali (a, b) 'nel tuo codice –

+0

Fantastico. Non sapevo di quella classe! Anche 'ObjectUtils.hashCode' è stato geniale. – Svish

+2

@ ÓscarLópez: non puoi farlo. Al compilatore non piacerà (a causa della collisione con 'Object.equals (Object)'). È qui che il metodo 'equal()' di Guava è più adatto allo –

0

String.valueOf() risolverà alcuni di questi problemi se il toString è implementato per le classi. Sputerà la risposta toString() o "null" se il puntatore è nullo.

+0

Dipende se vuoi che il valore di campo di 'null' sia uguale a quello con valore" null ". Nella maggior parte dei casi, direi che * non * è desiderabile. Dipende anche dal toString che corrisponde esattamente a ciò che è richiesto per la corrispondenza delle uguaglianze ... ed è anche probabile che sia piuttosto lento ... –

+0

Capisco perché SQL dice che null! = Null, ma non sono sempre d'accordo con questo approccio. Spesso, quando sto implementando equals, sto bene con null == null. Sono d'accordo con il commento sulla velocità, ma l'autore voleva evitare il controllo nullo, quindi stavo rispondendo alla domanda. – Thom

+0

Non sto parlando di 'null == null'. Sto parlando di 'null ==" null "'. –

4

vorrei scrivere in questo modo:

return field != null && other.field != null && field.equals(other.field); 

che non è elegante come la linea di codice C#, ma molto più breve poi il caso dell'albero hai postato.

+0

Sì, se fosse solo un campo che potrebbe essere una soluzione. Il problema è quando l'oggetto ha diversi campi da controllare. – Svish

+0

Ma cosa succede se la funzione ha fatto qualcosa in seguito se il risultato è vero? –

+1

Ma questo è sbagliato, e i due campi sono nulli? – maaartinus

6

Guava equal che fa questo:

public static boolean equal(@Nullable Object a, @Nullable Object b) { 
    return a == b || (a != null && a.equals(b)); 
    } 

o null object pattern

Guava ha anche il po correlati comparison chain e un carico di altri goodies.

+1

La cosa bella della loro chiamata il metodo 'equal' e non' equals' (come commons-lang) è il fatto che possa essere usata nelle importazioni statiche ... –

1

Come parte del progetto della moneta, ci fu una proposta per l'aggiunta di una serie di null-safe operators a Java. Purtroppo, non sono stati convertiti in Java 7, forse verranno visualizzati in Java 8. Here è l'idea generale di come funzionerebbero

36

Java 7 offre java.util.Objects.equals.

+4

Questo è il "nuovo" modo consigliato per farlo. @Svish, se è possibile modificare la risposta accettata per i futuri spettatori ... :) –

+3

NOTA: per Android, questo metodo richiede 'minimo API'> = 19. – ToolmakerSteve

+1

sì, questo metodo consente di evitare' NullPointerException'. Si noti che 'Object.equals (null, null)' restituisce true. – kiedysktos

2

Accetto tutte le risposte tecnicamente. Praticamente non userò nessuno di loro nel codice che ho sotto controllo perché tutte le soluzioni fornite stanno lavorando attorno al problema principale: valori null. MANTENERE IL MODELLO DEL CUORE ESENTE DA VALORI NULLI, e in questo caso la domanda è obsoleta.

Ai bordi di sistema come le librerie di terze parti a volte si devono trattare valori nulli. Dovrebbero essere convertiti in valori significativi per il modello principale. Lì le soluzioni fornite sono utili.

Anche se Oracle raccomanda di uguale-Metodi per essere NULL-safe, pensa che: Una volta che si accetta valori nulli vostro modello sta diventando fragile. Il metodo equals non sarà l'ultimo metodo in cui verificherai il null. Devi gestire i controlli null nella gerarchia delle chiamate di metodo. I metodi potrebbero non essere più riutilizzabili fuori dalla scatola. Presto, ogni parametro verrà controllato per null.

Ho visto entrambe le parti:

Da un lato il codice completo di controlli nulli, metodi che non si fidano più un singolo parametro e gli sviluppatori che hanno paura di dimenticare un controllo nullo.

D'altro codice lato con istruzioni espressivi pieni che fare affermazioni chiare abbiano oggetti pieno funzionamento che possono essere utilizzati senza timore di NullPointerExceptions.

0

Usa == operatore quando si verifica per i riferimenti agli oggetti, se entrambi i riferimenti si riferiscono allo stesso oggetto che restituirà true. Altrimenti, se stai cercando il contenuto dell'oggetto, vai con il metodo .equals degli oggetti.

Quindi null significa che non ha alcuna posizione di memoria data in heap. Quindi può essere semplicemente controllato con l'operatore '=='.

1

In realtà ognuno segue c'è proprio modo di fare questo e anche vorrei introdurre Groovy qui.

C'è un modo

field == null ? false : true; // Quindi, in pratica si tornerà vero quando non è nullo.

In Groovy esiste un operatore di sicurezza nulla per gli oggetti. Consente di prendere un esempio per la classe

A { 
String name = "test1" 
String surName = "test2" 

public String returnName() { 

return name + surName 
} 

} 

A a = null a?.name // Operatore oggetto ? effettivamente verificare se una è null o meno. quindi invocherà il nome.

Nota: non ho fatto domanda e virgola nel codice come questo non si richiede in Groovy.