2009-02-19 17 views
12

Estoy esperando un "no" en esta pregunta.¿Se puede almacenar una variable dentro de una cláusula if?

Me interesaba si puede guardar una variable al mismo tiempo cuando la registra en una cláusula if.

Digamos que tengo este código.

if(foo!=null){ 
    if(foo.getBar()!=null){ 
    Bar bar = foo.getBar(); 
    System.out.println("Success: " + bar); 
    } else { 
    System.out.println("Failure."); 
    } 
} else { 
    System.out.println("Failure."); 
} 

I manejo ahora en "falla": declara independientemente, incluso si el resultado es el mismo. Podría juntarlos así:

if(foo!=null && foo.getBar()!=null){ 
    Bar bar = foo.getBar(); 
    System.out.println("Success: " + bar); 
} else { 
    System.out.println("Failure."); 
} 

Mucho más ordenado código ya. si foo es nulo, se detendrá allí y no probará foo.getBar (en el si) así que no obtendré un NPE. Lo último que me gustaría mejorar, y la pregunta principal: ¿Realmente me dio a llamar a foo.getBar() dos veces? Sería bueno alejarse de la segunda llamada idéntica si getBar() sería una operación muy pesada. Así que me pregunto si hay alguna manera es posible hacer algo similar a esto:

if(foo!=null && (Bar bar = foo.getBar())!=null){ 
    Bar bar = foo.getBar(); 
    System.out.println("Success: " + bar); 
} else { 
    System.out.println("Failure."); 
} 

tendría que romperlo hasta dos diferentes si es nuevo si me gustaría hacer

Bar bar = foo.getBar(); 
if (bar!=null) ... 
+0

Por cierto, es "falla". –

Respuesta

25

Esto es lo más cercano que puede obtener:

Bar bar; 
if(foo!=null && (bar = foo.getBar())!=null){ 
    System.out.println("Success: " + bar); 
} else { 
    System.out.println("Failiure."); 
} 
+0

Sí, esto realmente funcionó. Intenté tener (Bar bar = foo.getBar())! = Null dentro de if, pero a java no parece gustarle tener la inicialización del Object dentro de if-clause. ¡Gracias! –

10

tengo se utiliza esta técnica cuando se repite a través de líneas de un BufferedReader:

BufferedReader br = // create reader 
String line 
while ((line = br.readLine()) != null) { 
    // process the line 
} 

Así que sí, se puede hacer una asignación, y el resultado de que será la variable lado izquierdo, que luego se puede comprobar. Sin embargo, no es legal declarar variables dentro de una prueba, ya que solo se definirían en esa expresión.

7

si desea limitar el alcance de barra de bar que me gustaría añadir {y} alrededor del código que Michael ha escrito.

 
void foo() 
{ 
    // some code ... 

    // this block limits the scope of "Bar bar" so that the rest of the method cannot see 
    // it. 
    { 
     Bar bar; 
     if(foo!=null && (bar = foo.getBar())!=null){ 
      System.out.println("Success: " + bar); 
     } else { 
      System.out.println("Failiure."); 
     } 
    } 
} 

Es posible que también desee comprobar en el patrón de objeto nulo si tiene sentido. Personalmente trato de evitar que las cosas sean nulas si puedo ... realmente pensar si quieres que se permita nulo o no.

2

Desde el departamento "Mi lenguaje de programación es mejor que su lenguaje de programación": en Groovy, puede utilizar el "?." operador:

Bar bar = foo?.bar 
if (bar != null) { 
} 

En Java, esto es buen patrón (*):

Bar bar = foo == null ? null : foo.getBar(); 
if (bar != null) { 
} 

*: Algo que puede guardar en su alcance.

1

Tres puntos que fallan completamente al responder a la pregunta:

null es malo. No escriba métodos que lo devuelvan. Tu problema de ejemplo desaparecería.

Creo que es posible que se esté perdiendo la encapsulación. En lugar de foo.getBar(), ¿se podría hacer la interfaz de foo de modo que realice una operación de "no preguntar"?

Los efectos secundarios en la expresión tienden a causar código incorrecto. Prefiere más, líneas más simples a menos, líneas con errores. La excepción habitual si se usa ++ para incrementar un índice al acceder a un búfer, o algoritmos de estilo de iterador similares.

Cuestiones relacionadas