java logical-operators short-circuiting

Evaluación de corto circuito en Java



logical-operators short-circuiting (7)

Gran misterio Copié su línea de código y probé con perfectAgent == null , entry == null , entry.getKey() == null y combinaciones de estos: No NPE en mi banco de pruebas (Java 1.6).

Cualquiera que sea el error molesto que es, dudo que tenga algo que ver con la evaluación de cortocircuito. Si es esta línea la que causa NPE, entonces, por lo que puedo decir, perfectAgent no es nulo. Buena suerte y - muéstranos el error una vez que lo hayas atrapado :)

Pensé que Java tenía una evaluación de cortocircuito, pero esta línea todavía está lanzando una excepción de puntero nulo:

if( (perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey())) ) {

En este caso, perfectAgent es null , así que solo quiero que toda la expresión devuelva false , pero mi aplicación aún falla en esta línea con una NullPointerException.

EDITAR, respuesta general:

Como perfectAgent es null , no debe ejecutarse nada a la derecha de && , ya que es imposible que la expresión sea verdadera. Más al punto, es imposible ejecutar perfectAgent.getAddress() ya que perfectAgent no contiene una referencia válida (es nula y todo). Estoy tratando de usar la evaluación de cortocircuitos para no tener que buscar nulos en una declaración por separado, ya que eso hace que la lógica sea más descuidada.

EDIT 2 (o, soy un idiota): Sí, como muchas cosas en la vida, descubres la respuesta justo después de anunciar al mundo que eres un imbécil. En este caso, había desactivado la autoedición de Eclipse mientras hacía otra cosa y no lo había vuelto a encender, así que estaba depurando archivos de clase que no coincidían con mi fuente.


Hay tres referencias distintas de perfectAgent que podrían ser nulas:

  • perfectAgent.getAddress ()
  • entrada
  • entry.getKey ()

Divida la sentencia o ejecútela en un depurador.


Intenta formatear tu código de esta manera:

if( (perfectAgent != null) && ( perfectAgent.getAddress() .equals( entry.getKey() ) ) ) {

Debería darte una mejor entrada de línea de seguimiento de pila.


Java tiene evaluación de corto circuito. Quizás la entry es null y, por entry.getKey() tanto, entry.getKey() está causando la entry.getKey() NullPointerException . Otra posibilidad es que getAddress() devuelva un null o tenga una NullPointerException dentro de algún lugar (si es más complicado que una simple declaración de return ).

EDITAR: Veo tu edición donde reclamas esto:

Más al punto, es imposible ejecutar perfectAgent.getAddress() ...

Pero, ¿qué perfectAgent.getAddress() si perfectAgent.getAddress() se ejecuta correctamente y devuelve null ? Mira a lo que me refiero ...


Si perfectAgent es genuinamente nulo, ese código no generará una excepción (al menos suponiendo que no haya cosas extrañas en los hilos, cambiándolas de no nulas a nulas en la mitad de la expresión). Me sorprendería muchísimo si pudieras producir un programa corto pero completo que demuestre que lo está haciendo.

Así que sí, tu intuición es correcta, esto no debería ser un problema. Busque la causa en otro lugar. Sospecho firmemente que perfectAgent no es en realidad nulo, y que se está ejecutando en cualquiera de las otras situaciones en ese código que podrían causar una excepción.

Le sugiero que intente extraer ese fragmento de código en un breve pero completo ejemplo: si puede hacerlo, me comeré mi sombrero metafórico; Si no es así, es de esperar que encuentre el problema mientras intenta la extracción.

¿Qué te hace pensar que perfectAgent realmente es nulo? Intente insertar este código antes de que:

if (perfectAgent == null) { System.out.println("Yup, it''s null"); }

Otra posibilidad muy, muy delgada es que te has topado con un error JIT, pero lo dudo mucho.


Usted se asegura de que perfectAgent no sea nulo, por lo que uno o más de perfectAgent.getAddress() o entry o entry.getKey() deben ser nulos. O getAddress () o getKey () están golpeando un NPE en su implementación.

Para depurar este tipo de cosas, mire primero el seguimiento de la pila para fijar la ubicación. Esto le diría si está sucediendo en getAddress () o en getKey () o en el fragmento de código pegado que los llama. A continuación, si está en este fragmento, agregue algo de código antes de la prueba if que es nula. Puede usar buenos viejos System.err.println () o assertions . (Si usa aserciones, asegúrese de habilitarlas con el indicador -enableassertions del comando java).

Actualización: mi interpretación resultó ser errónea ... el problema presentaba dos hechos contradictorios (había un NPE en esta línea y, sin embargo, el cortocircuito debería haber ocurrido) y asumí automáticamente que el primer hecho era verdadero y el segundo falso cuando, de hecho, fue un problema completamente diferente debido a la desactivación de la compilación automática en Eclipse. Duh! Al depurar algo "imposible" ayuda ser radicalmente escéptico.


Lección de depuración avanzada # 1:

Si se encuentra con un error aparentemente imposible (por ejemplo, uno que contradice su conocimiento sobre Java), haga lo siguiente:

  • Consulte un libro de texto de buena reputación (o, mejor aún, la norma relevante) para confirmar que su comprensión no es errónea. (En este caso, su comprensión fue correcta, y cualquier libro de texto medio decente lo confirmaría en un minuto).

  • Verifica todas las cosas estúpidas que podrías haber hecho que podrían causar el error imposible. Cosas como no guardar un archivo, no hacer una compilación completa, ejecutar una versión antigua / obsoleta de la aplicación, estar en el directorio incorrecto, etc.

En resumen, aprende a dudar un poco más.