2011-04-18 10 views
60

Consulte el siguiente código y explique el comportamiento de salida.Comportamiento de la declaración de devolución en catch y finalmente

public class MyFinalTest { 

    public int doMethod(){ 
     try{ 
      throw new Exception(); 
     } 
     catch(Exception ex){ 
      return 5; 
     } 
     finally{ 
      return 10; 
     } 
    } 

    public static void main(String[] args) { 

     MyFinalTest testEx = new MyFinalTest(); 
     int rVal = testEx.doMethod(); 
     System.out.println("The return Val : "+rVal); 
    } 

} 

El resultado es el retorno Val: 10.

Eclipse muestra una advertencia: finally block does not complete normally.

¿Qué sucede con la declaración de devolución en el bloque catch?

+0

posible duplicado de [¿por qué el cambio de la variable devuelta en un fin de no bloquear cambiar el valor de retorno?] (http://stackoverflow.com/questions/ 16030858/why-does-changing-the-returned-variable-in-a-finally-block-not-change-the-return) – fglez

+2

Una pregunta de entrevista muy popular. –

Respuesta

67

Se reemplaza por uno en finally, porque finally se ejecuta después de todo lo demás.

Es por eso que, una regla de oro - nunca regresa de finally. Eclipse, por ejemplo, muestra advertencias para ese fragmento: "finalmente el bloque no se completa normalmente"

49

finally siempre se ejecuta (la única excepción es System.exit()). Se puede pensar en este comportamiento de esta manera:

  1. produce una excepción
  2. Excepción es capturado y valor de retorno se establece en 5
  3. último bloque es ejecutado y el valor de retorno se establece en 10
  4. El función devuelve
+0

Reglas generales del bloque try/catch: 1) Nunca devuelva un valor en el bloque finally. 2) Evite lanzar una excepción por fin o atrapar negro, ya que oscurece la excepción original. – Matt

+12

Decir finalmente que siempre se ejecuta es algo muy peligroso. Realmente no puede confiar en que se ejecute para operaciones de misión crítica. Considere algo como un corte de energía, una corrupción/accidente de JVM, etc. Sé que suena un poco quisquilloso, pero siempre es una palabra fuerte, y creo que a veces olvidamos que vivimos en el mundo real donde los desastres como ese lo hacen ocurrir. – corsiKa

3

siempre se ejecuta el bloque finally (si se ejecutó la prueba de juego) así que antes de que el método devuelve 5 como en el bloque de catch, ejecuta el finally bloquear y devuelve 10.

17

Esta es una pregunta fácil si recuerda el diseño de bajo nivel de la máquina virtual.

  1. El valor de retorno se coloca en la pila mediante el código de captura.
  2. Después, el código finalmente se ejecuta y sobrescribe el valor en la pila.
  3. Luego, el método regresa con el valor más actualizado (10) para ser utilizado por la persona que llama.

Si no está seguro de cosas como esta, vuelva a su comprensión del sistema subyacente (en última instancia, vaya al nivel de ensamblador).

(funny sidenote)

0

la sección finalmente se ejecutará siempre ejecutar. p.ej. si tiene algo que liberar, o cerrar la sesión, si se produce un error, vaya a la sección de captura que finalmente se ejecutará.

Session session // opened some session 
try 
{ 
// some error 
} 
catch { log.error } 
finally 
{ session.logout();} 

no debería utilizarse para devolver nada. puedes usar fuera de.

3

enter image description here

bloque finally siempre se ejecutan a menos que y hasta que System.exit declaración() es el primero en bloque finally.

Por lo tanto, aquí en el ejemplo anterior, la instrucción try arroja la ejecución y obtiene catch in catch block. Hay declaración de retorno con el valor por lo que en el valor de llamada de la pila se agrega más adelante finalmente se ejecuta el bloque y se agrega el último valor de retorno en la parte superior de la pila al devolver el valor, la pila devuelve el último valor según el comportamiento de pila "ÚLTIMO In First Out" para que vuelva valor como 10.

Cuestiones relacionadas