Как работает возврат в try, catch, наконец, в Java?
Я не могу точно понять, как работает return
в try
, catch
.
- Если я
try
и, finally
не catch
, я могу return
внутри блока try
. - Если я
try
, catch
, finally
, я не могу поместить return
в блок try
. - Если у меня есть блок
catch
, я должен поместить return
за пределы блоков try
, catch
, finally
. - Если я удалю блок
catch
и throw Exception
, я могу поместить его return
в блок try
.
Как они работают точно? Почему я не могу поместить return
в блок try
?
Код с 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;
}
Код с try
, finally
без 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);
}
}
Ответы
Ответ 1
Да, это сбивает с толку.
В Java все пути управления программой функции non- void
должны заканчиваться return
или вызывать исключение. То, что правило ставило хорошо и просто.
Но, в мерзости, Java позволяет вам добавить дополнительный return
в блок finally
, который переопределяет любой ранее встреченный return
:
try {
return foo; // This is evaluated...
} finally {
return bar; // ...and so is this one, and the previous 'return' is discarded
}
Ответ 2
И если я попытаюсь, поймаю, я не смогу вернуть return в блок try.
Вы абсолютно можете. Вам просто нужно убедиться, что каждый путь управления в вашем методе завершен правильно. Под этим я подразумеваю: каждый путь выполнения через ваш метод заканчивается либо return
, либо throw
.
Например, следующие работы:
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");
}
}
Здесь у вас есть два возможных пути выполнения:
-
final int я = foo()
- или
-
System.out.println("finally")
-
return i
- или же
-
System.out.println(e)
-
System.out.println("finally")
-
throw e
Путь (1, 2) берется, если исключение не выбрано foo
. Путь (1, 3) берется, если выбрано исключение. Обратите внимание, что в обоих случаях блок finally
выполняется до того, как метод оставлен.
Ответ 3
Наконец, блок всегда будет выполняться, даже если мы поймаем исключение в блоке catch или даже наш блок try выполним, как ожидалось.
поэтому, когда окончательный блок будет выполняться с потоком...
если у нас есть оператор return внутри блока try/catch, то перед выполнением оператора return окончательный блок будет выполнен (например, для закрытия соединения или ввода-вывода)
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;
}
}
но если у вас есть оператор return внутри выражения finally, то он переопределит оператор return внутри блока try или catch.
Ответ 4
Это нормальный поток программ при обработке исключений. Наличие блокировки в коде создает случай, когда путь кода может напрямую входить в блок catch. Это наносит ущерб мандату с возвратом в методе, который возвращает что-то. Возможно, что оператор return не может быть выполнен, если возникает исключение, поэтому компилятор выдает ошибку. Поэтому, чтобы избежать этой проблемы, вам понадобится как минимум еще один оператор return в методе.
Если вы добавили оператор return в блок try-finally, и у вас нет блокировки catch, это нормально. Здесь нет случая аномального кода.
Если вы добавили оператор return в блок try и у вас есть catch block, вы можете либо добавить return в catch catch, либо в конце метода.
Если вы добавили оператор return в блок try и у вас есть блок catch и, наконец, блокируете, то вы можете либо добавить возврат в блок catch, либо в конце метода. Вы также можете добавить возврат в блок finally. Если вы используете eclipse, он будет генерировать предупреждение, которое может быть подавлено, используя приведенное выше определение метода -
@SuppressWarnings("finally")
Ответ 5
Я думаю, это то, о чем вы спрашиваете:
И если я попытаюсь, поймаю, я не смогу вернуть return в блок try.
Поэтому, если вы добавите блок catch
, вы не можете поместить return
в блок try.
Проблема в том, что если вы добавляете catch
управление переходит через, и вам нужно return
в конце метода или это синтаксическая ошибка. Я не тестировал это, но я предполагаю, что вы могли бы поместить return
в блок try
, но вам также нужно будет добавить его внутри catch
или в конце метода, как сейчас.
Ответ 6
Во втором примере, если проверенное исключение происходит, оно переходит к вызову метода.
В первом примере, если проверенное исключение происходит, оно обрабатывается одним и тем же методом, поскольку блок catch берет на себя ответственность за обработку исключения.
если вы пишете оператор return в блоке catch, то он работает.
т.е.
try{
return ..
}catch(Exception e){
return ..
}finally{
}
Но это не хорошая практика программирования.
Ответ 7
При использовании публичных функций, отличных от функций void, вы должны вернуть что-то или ваша функция не будет.