2010-11-12 6 views
13

me tienen dicho código:¿Comprueba Java todos los argumentos en el operador "&&" (y) incluso si uno de ellos es falso?

if(object != null && object.field != null){ 
    object.field = "foo"; 
} 

Supongamos que objeto es nulo.

¿Este código da como resultado nullPointerException o simplemente si no se ejecutará la instrucción?

Si lo hace, ¿cómo refactorizar este código para que sea más elegante (si es posible, por supuesto)?

+3

Juega un poco: http://ideone.com/KRMwj – zengr

+0

Y el otro caso: http://ideone.com/NAP0Q – zengr

Respuesta

8

Java tiene evaluación de cortocircuito, es decir, el código debe estar bien

+0

Java tiene corta -circuito, cierto, pero solo se usa en este ejemplo debido al uso de '&&' en oposición a '&'. '&' daría como resultado 'NullPointerException'. –

+0

"&& en comparación con &"? ¿En qué parte de la pregunta ves eso? –

+1

En ninguna parte, solo estaba agregando ese punto porque el operador '&' * no * tiene un cortocircuito. –

20

&& hace cortocircuito mientras & no lo haría.

Pero con preguntas simples como esta, lo mejor es intentarlo (ideone puede ayudar cuando no tiene acceso a una máquina).

& & - http://ideone.com/LvV6w & - http://ideone.com/X5PdU

Finalmente el lugar para comprobar si hay seguro que sería el JLS §15.23. No es la cosa más fácil de leer, los estados sección relevante: El operador & & es como & (§15.22.2), pero evalúa su operador de la derecha sólo si el valor de su operando de la izquierda es cierto.

2

La mejor manera de averiguarlo sería intentarlo, especialmente para una pregunta de una sola línea. Hubiera sido más rápido, también.

La respuesta es que Java no ejecutará el cuerpo del "si".

+0

Es cierto, pero "prueba por experimentación" no siempre es el mejor enfoque. Piense en probar cosas relacionadas con la concurrencia en una máquina de un solo núcleo, por ejemplo. Siempre es bueno preguntar y comprender la mecánica subyacente en lugar de esperar que sus pruebas incluyan todos los casos extremos para la caja negra ... –

+1

Recuerde, estamos hablando de una línea de código aquí. ¿"Casos del borde"? No en este caso. – duffymo

2

Esto no arroja ningún NullPointerException. La condición se evaluará de izquierda a derecha y en el momento en que se encuentre la primera expresión false, no evaluará la expresión restante.

1

Java tiene una evaluación de cortocircuito, por lo que estará bien.

El código se ve bien para mí, pero ¿realmente necesita verificar object.field != null? Creo que la prueba se puede omitir ya que nunca se usa la variable, simplemente configúrela.

En una nota al margen, la mayoría de los programadores no accederían directamente a los campos (object.field) sino a través de getters/setters (object.setField(x);). Sin más contexto para continuar, no puedo decir si esto es apropiado en su caso.

0

Si desea que todas sus expresiones booleanas se evalúen independientemente del valor de verdad de cada una, puede usar & y | en lugar de & & y ||. Sin embargo, asegúrese de usarlos solo en expresiones booleanas. A diferencia de & & y ||, & y | también tienen un significado para los tipos numéricos que es completamente diferente de su significado para los booleanos. http://ibiblio.org/java/course/week2/46.html

1

& & y || las condiciones se detienen en el punto en que pueden decidir si la condición es verdadera/falsa, en su caso, la condición se detendrá justo después de object != null y creo que su código está bien para este caso

0

Aunque aquí podría funcionar el cortocircuito, no es una garantía de que (como he hecho muchas veces) obtendrá el orden incorrecto al escribir otro, sería mejor anotar esas sentencias if y definir el orden en que desea que se rompan las comprobaciones booleanas:

if(object != null) 
{ 
    if(object.field != null) 
    { 
     object.field = "foo"; 
    } 
} 

Esto hace exactamente lo mismo que básicamente dice, si la primera verificación booleana falla, no haga la segunda; también es nullPointerException seguro como object.field no se verificará a menos que el objeto no sea nulo

El uso de cortocircuitos en booleanos puede volverse molesto más adelante ya que cuando se tiene una instrucción bool múltiple se vuelve más complicado depurar de manera eficiente qué parte cortocircuitado

2

¡Una forma de saberlo! ¡Pruébalo! ¿Cómo? Así, hacer un método que imprime algo:

public static boolean test(int i) 
{ 
    System.out.println(i); 
    return false; 
} 

... 

if (test(1) && test(2) && test(3)) 
{ 
    // not reached 
} 

Esta impresora:

1 

Así que la respuesta a su pregunta es "no".

Cuestiones relacionadas