2011-10-25 15 views
15

puedo encontrar cosas como esta bastante molesto y desagradable en equals métodos:Cómo prevenir cheque nulo antes es igual a

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

en C# que podría haber hecho esto:

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

¿Existe algo parecido en Java, o ¿cuál es la forma preferida de hacer este tipo si algo?

+1

Creo que este hilo le resultará útil: http://stackoverflow.com/questions/271526/how-to-avoid-null-statements-in-java – hovanessyan

+0

Interesante, claro. Útil ... personalmente, en su mayoría solo planteó más preguntas: p – Svish

Respuesta

23

Use commons-lang: Código

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

Fuente:

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

De Apache

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

Eso es aproximadamente equivalente a lo que se hace en C#

+0

Y si importa ese método estáticamente (importe org.apache.commons.lang.ObjectUtils.equals estáticos;) entonces simplemente puede escribir 'equals (a, b) 'en su código –

+0

Impresionante. ¡No sabía sobre esa clase! El 'ObjectUtils.hashCode' también fue brillante. – Svish

+2

@ ÓscarLópez: No puedes hacer eso. Al compilador no le gustará (debido a la colisión con 'Object.equals (Object)'). Ahí es donde el método 'igual()' de Guava es más adecuado –

0

String.valueOf() resolverá algunos de esos problemas si se implementa toString para sus clases. Escupirá la respuesta toString() o "null" si el puntero es nulo.

+0

Eso depende de si desea que un valor de campo 'null' sea igual a uno con el valor" nulo ". Diría que en la mayoría de los casos eso es * no * deseable. También depende de que toString coincida exactamente con lo que se requiere para la coincidencia de igualdad ... y también es probable que sea más lento ... –

+0

Entiendo por qué SQL dice que null! = Null, pero no siempre estoy de acuerdo con ese enfoque. Con frecuencia, cuando estoy implementando iguales, estoy bien con null == null. Estoy de acuerdo con el comentario de velocidad, pero el autor quería evitar la verificación nula, así que estaba respondiendo la pregunta. – Thom

+0

No estoy hablando de 'null == null'. Estoy hablando de 'null ==" nulo "'. –

4

que iba a escribir de esta manera:

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

que no es tan elegante como la línea de código en C#, pero mucho más corto que el árbol si informados.

+0

Sí, si solo hubiera un campo que podría ser una solución. El problema es cuando el objeto tiene varios campos para verificar. – Svish

+0

Pero, ¿y si la función ha hecho algo después si el resultado es cierto? –

+1

Pero esto está mal, ¿qué pasa con ambos campos siendo nulo? – maaartinus

6

Guava equal que hace esto:

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

o null object pattern

guayaba también tiene el algo relacionado comparison chain y una carga de otro goodies.

+1

Lo bueno de que llamen al método 'igual' y no' igual' (como commons-lang) es el hecho de que se puede usar en importaciones estáticas ... –

1

Como parte de Project Coin, hubo una propuesta para agregar una serie de null-safe operators a Java. Lamentablemente, no lo hicieron en Java 7, tal vez aparecerán en Java 8. Here es la idea general de cómo funcionarían

36

Java 7 ofrece java.util.Objects.equals.

+4

Esta es la "nueva" forma recomendada de hacerlo. @Svish, si puede cambiar la respuesta aceptada para futuros espectadores ... :) –

+3

NOTA: Para Android, este método requiere 'mínimo API'> = 19. – ToolmakerSteve

+1

sí, este método ayuda a evitar' NullPointerException'. Tenga en cuenta que 'Object.equals (null, null)' devuelve verdadero. – kiedysktos

2

Acepto todas las respuestas técnicamente. Prácticamente no usaré ninguno de ellos en el código que tengo bajo control porque todas las soluciones proporcionadas están trabajando en torno al problema central: valores nulos. MANTENGA SU MODELO BÁSICO LIBRE DE VALORES NULOS, y la pregunta es obsoleta en este caso.

En los bordes del sistema como las bibliotecas de terceros, a veces hay que tratar con valores nulos. Deben convertirse en valores significativos para el modelo central. Allí las soluciones dadas son útiles.

Incluso si Oracle recomienda los iguales: los métodos son nulos, piense en eso: una vez que acepta valores nulos, su modelo se vuelve frágil. El método igual no será el último método en el que comprobará nulo. Debe administrar null-checks en su jerarquía de llamadas a métodos. Es posible que los métodos ya no se puedan volver a utilizar de manera inmediata. Pronto, cada parámetro se comprobará nulo.

vi dos lados:

Por un lado completo del código de cheques nulos, métodos que no confían en un único parámetro más y desarrolladores que tienen miedo de olvidar un cheque nulo.

En el otro lado, el código con declaraciones expresivas completas que hacen afirmaciones claras de tener objetos de pleno funcionamiento que se pueden utilizar sin temor a NullPointerExceptions.

0

Utilice el operador == cuando esté buscando referencias de objetos, si ambas referencias se refieren al mismo objeto, devolverá verdadero. De lo contrario, si está buscando contenido de objetos, vaya con el método de objetos .equals.

Tan nulo significa que no tiene ninguna ubicación de memoria en el montón. Por lo tanto, se puede verificar simplemente con el operador '=='.

1

En realidad, todos siguen su propia forma de hacer esto y también me gustaría presentarles groovy aquí.

Hay una manera

field == null ? false : true; // Así que básicamente se volverá verdad cuando no es nulo.

En groovy no hay operador seguro para los objetos. Vamos a tomar un ejemplo para la clase

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

public String returnName() { 

return name + surName 
} 

} 

A a = null a?.name // operador mencionado ? se verifica si en realidad es un null o no. entonces invocará el nombre.

Nota: no apliqué semi puntos en el código ya que esto no es necesario en groovy.