java - Devoluciones múltiples: ¿Cuál establece el valor de retorno final?
return finally (6)
Después de leer el ByteCode del programa, el código es el siguiente:
Las instrucciones finally block están en línea antes de la declaración return del bloque try, por lo que el retorno del bloque finally se ejecuta primero y la declaración return original nunca lo hace.
Para el programa:
String test() {
try {
System.out.println("try");
return "1";
} finally {
System.out.println("finally");
return "2";
}
}
Se convierte en:
String test()
{
System.out.println("try");
String s = "1"; //temporary variable
System.out.println("finally");
return "2";
Exception exception;
exception;
System.out.println("finally");
return "2";
}
Y para el programa: con catch block:
String test() {
try {
System.out.println("try");
return "1";
} catch (RuntimeException e) {
System.out.println("catch");
return "2";
} finally {
System.out.println("finally");
return "3";
}
}
Convierte a:
String test()
{
System.out.println("try");
String s = "1";
System.out.println("finally");
return "3";
RuntimeException e;
e;
System.out.println("catch");
String s1 = "2";
System.out.println("finally");
return "3";
Exception exception;
exception;
System.out.println("finally");
return "3";
}
Nota: cumplió con JDK 1.7 y Descompilado usando Cavaj.
Dado este código:
String test() {
try {
return "1";
} finally {
return "2";
}
}
¿Las especificaciones del lenguaje definen el valor de retorno de una llamada a test()
? En otras palabras: ¿siempre es igual en cada JVM?
En Sun JVM, el valor de retorno es 2
, pero quiero estar seguro de que esto no depende de VM.
El bloque finally siempre se ejecutará excepto en el siguiente ejemplo:
String test() {
try {
System.exit(0);
} finally {
return "2";
}
}
En este caso, la JVM se detendrá, sin ejecutar el bloque finally
.
Entonces en tu ejemplo, el valor de retorno será 2
.
Puede consultar el siguiente enlace. Espero que proporcione todos los detalles:
http://www.programmerinterview.com/index.php/java-questions/will-finally-run-after-return/
Dice que finalmente el bloque siempre se ejecutará, incluso try o catch block tiene return statement. Y si finalmente el bloque también tiene declaración de retorno, esto anulará la declaración de devolución que está dentro de try o catch block y en este caso cualquier excepción lanzada en try / catch será descartada (mal enfoque).
Gracias, Chethan
Sí, la especificación del lenguaje define que "2" es el resultado. Si una VM lo hace de manera diferente, no es compatible con las especificaciones.
La mayoría de los compiladores se quejarán al respecto. Eclipse, por ejemplo, afirmará que el bloque de retorno nunca se ejecutará, pero está mal.
Es sorprendentemente mala práctica escribir código así, no lo hagas nunca :)
Sí, la especificación del lenguaje Java es muy clara en este tema ( 14.20.2 ):
Una instrucción try con un bloque finally se ejecuta ejecutando primero el bloque try. Entonces hay una opción:
- Si la ejecución del bloque try se completa normalmente, [...]
- Si la ejecución del bloque try se completa abruptamente debido a un lanzamiento de un valor V, [...]
- Si la ejecución del bloque try se completa bruscamente por cualquier otro motivo R, entonces se ejecuta el bloque finally. Entonces hay una opción:
- Si el bloque finally se completa normalmente, [...]
- Si el bloque final se completa abruptamente por la razón S, entonces la instrucción try se completa abruptamente por la razón S (y la razón R se descarta).
Sí, si devuelve algo del bloque finally
, reemplazará lo que haya devuelto del bloque try
o catch
.
Lo mismo es cierto también para las excepciones . Si arrojas algo en el bloque finally
, esa excepción reemplazará cualquier excepción que se haya lanzado en el bloque try
o catch
. Así que tenga cuidado de nunca tirar algo en el bloque final, ya que puede ocultar la razón original de una falla.