try catch resource java 7
¿Cómo funciona el retorno en try, catch, finalmente en Java? (7)
No puedo entender exactamente cómo funciona el return
en el try
, catch
.
- Si lo he
try
y,finally
sincatch
, puedo poner elreturn
dentro del bloquetry
. - Si tengo
try
,catch
,finally
, no puedo ponerreturn
en el bloquetry
. - Si tengo un bloque
catch
, debo poner elreturn
fuera deltry
,catch
, yfinally
bloques. - Si elimino el bloque
catch
ythrow Exception
, puedo poner lareturn
dentro del bloquetry
.
¿Cómo funcionan exactamente? ¿Por qué no puedo poner la return
en el bloque try
?
Codigo con try
, catch
, finally
public int insertUser(UserBean user) {
int status = 0;
Connection myConn = null;
PreparedStatement myStmt = null;
try {
// Get database connection
myConn = dataSource.getConnection();
// Create SQL query for insert
String sql = "INSERT INTO user "
+ "(user_name, name, password) "
+ "VALUES (?, ?, ?)";
myStmt = myConn.prepareStatement(sql);
// Set the parameter values for the student
myStmt.setString(1, user.getUsername());
myStmt.setString(2, user.getName());
myStmt.setString(3, user.getPassword());
// Execute SQL insert
myStmt.execute();
} catch (Exception exc) {
System.out.println(exc);
} finally {
// Clean up JDBC objects
close(myConn, myStmt, null);
}
return status;
}
Código con try
, finally
sin catch
public int insertUser(UserBean user) throws Exception {
int status = 0;
Connection myConn = null;
PreparedStatement myStmt = null;
try {
// Get database connection
myConn = dataSource.getConnection();
// Create SQL query for insert
String sql = "INSERT INTO user "
+ "(user_name, name, password) "
+ "VALUES (?, ?, ?)";
myStmt = myConn.prepareStatement(sql);
// Set the parameter values for the student
myStmt.setString(1, user.getUsername());
myStmt.setString(2, user.getName());
myStmt.setString(3, user.getPassword());
// Execute SQL insert
myStmt.execute();
return status;
} finally {
// Clean up JDBC objects
close(myConn, myStmt, null);
}
}
Y si tengo intento, captura, finalmente no puedo poner retorno en el bloque intento.
Absolutamente puedes. Solo debe asegurarse de que todas las rutas de control en su método terminen correctamente. Con eso quiero decir: cada camino de ejecución a través de su método termina en una return
o en un throw
.
Por ejemplo, los siguientes trabajos:
int foo() throws Exception { … }
int bar() throws Exception {
try {
final int i = foo();
return i;
} catch (Exception e) {
System.out.println(e);
throw e;
} finally {
System.out.println("finally");
}
}
Aquí tienes dos posibles caminos de ejecución:
-
final int i = foo()
- ya sea
-
System.out.println("finally")
-
return i
-
- o
-
System.out.println(e)
-
System.out.println("finally")
-
throw e
-
La ruta (1, 2) se toma si foo
no genera ninguna excepción. La ruta (1, 3) se toma si se lanza una excepción. Observe cómo, en ambos casos, el bloque finally
se ejecuta antes de dejar el método.
Creo que esto es lo que estás preguntando:
Y si tengo intento, captura, finalmente no puedo poner retorno en el bloque intento.
Entonces, si agrega un bloque catch
, no puede poner una return
en el bloque try.
El problema es que si agrega un catch
, el control cae y necesita un return
al final del método o es un error de sintaxis. No he probado esto, pero supongo que podría poner una return
en el bloque try
, pero también tendría que agregar uno dentro del catch
o al final del método como lo ha hecho ahora.
Cuando utilice una función pública distinta de las funciones de vacío, debe devolver algo o su función no lo hará.
En el segundo ejemplo, si se produce la excepción marcada, se pasa a llamar a un método.
En el primer ejemplo, si la excepción marcada ocurre, entonces se maneja con el mismo método, ya que el bloque catch asume la responsabilidad de manejar la excepción.
Si escribe una declaración de retorno en el bloque catch, entonces funciona.
es decir,
try{
return ..
}catch(Exception e){
return ..
}finally{
}
Pero no es una buena práctica de programación.
Este es el flujo normal del programa cuando se trata el manejo de excepciones. Tener un bloque catch en el código crea un caso en el que la ruta del código puede saltar directamente al bloque catch. Esto anula el mandato de tener una declaración de retorno en el método que devuelve algo. Es posible que la declaración de retorno no se ejecute si se produce una excepción, por lo tanto, el compilador arroja un error. Entonces, para evitar este problema, necesita al menos 1 declaración de retorno más en un método.
Si ha agregado una declaración de retorno en el bloque try-finally y no tiene bloque catch, está bien. No hay ningún caso de ruta de código anormal aquí.
Si ha agregado una declaración de retorno en el bloque de prueba y tiene un bloque catch, entonces puede agregar retorno en el bloque catch o al final del método.
Si ha agregado una declaración de retorno en el bloque de prueba y tiene un bloque catch y un bloque finalmente, entonces puede agregar el retorno en el bloque catch o al final del método. También puede optar por agregar retorno en el bloque finalmente. Si está utilizando eclipse, se generará una advertencia que se puede suprimir utilizando la definición de método que se encuentra a continuación:
@SuppressWarnings("finally")
Sí, es confuso.
En Java, todas las rutas de control de programas de una función no void
deben terminar con una return
o lanzar una excepción. Esa es la regla puesta en orden y sencillamente.
Pero, en una abominación, Java le permite poner un return
adicional en un bloque finally
, que anula cualquier return
encontrado anteriormente:
try {
return foo; // This is evaluated...
} finally {
return bar; // ...and so is this one, and the previous `return` is discarded
}
Finalmente, el bloque siempre se ejecutará incluso si detectamos la excepción en el bloque catch o incluso si nuestro bloque try se ejecuta como se esperaba.
así que cuando finalmente se ejecutará el bloque en el flujo ...
si tenemos una declaración de retorno dentro del bloque try / catch, entonces, antes de ejecutar la instrucción de retorno, se ejecutará el bloque (como para cerrar la conexión o E / S)
function returnType process() {
try {
// some other statements
// before returning someValue, finally block will be executed
return someValue;
} catch(Exception ex) {
// some error logger statements
// before returning someError, finally block will be executed
return someError;
} finally {
// some connection/IO closing statements
// if we have return inside the finally block
// then it will override the return statement of try/catch block
return overrideTryCatchValue;
}
}
pero si tiene una declaración de retorno dentro de la declaración finally, entonces reemplazará la declaración de retorno dentro del bloque try o catch.