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);
}
}
はい、わかりにくいです。
Javaでは、all非void
関数のプログラム制御パスmustreturn
で終了するか、例外をスローします。それがニースのシンプルなルールです。
しかし、憎悪では、Javaは、以前に遭遇したものを上書きするreturn
ブロックにextrafinally
を置くことができます。 return
:
try {
return foo; // This is evaluated...
} finally {
return bar; // ...and so is this one, and the previous `return` is discarded
}
そして、もし私が試したなら、最後に、tryブロックにreturnを入れることはできません。
絶対にできます。メソッドのすべての制御パスが適切に終了することを確認する必要があります。つまり、メソッドを通るすべての実行パスは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");
}
}
_
ここには、2つの実行パスがあります。
final int i = foo()
System.out.println("finally")
return i
_System.out.println(e)
System.out.println("finally")
throw e
_foo
によって例外がスローされない場合、パス(1、2)が使用されます。例外がスローされた場合、パス(1、3)が使用されます。どちらの場合でも、finally
ブロックが実行される方法に注意してくださいbeforeメソッドが残されます。
最終的にブロックは、catch blockで例外をキャッチした場合、またはtryブロックが期待どおりに実行された場合でも常に実行されます。
そのため、最終的にブロックはフローで実行されます...
try/catchブロック内にreturnステートメントがある場合、returnステートメントを実行する前にfinally blockが実行されます(接続を閉じる場合など)またはI/O)
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ブロック内にあります。
これは、例外処理が関係する場合の通常のプログラムフローです。コードにcatchブロックがあると、コードパスがcatchブロックに直接ジャンプできる場合があります。これは、何かを返すメソッドにreturnステートメントを持つというマンデートを無効にします。例外が発生した場合、returnステートメントが実行されない可能性があるため、コンパイラーはエラーをスローします。そのため、この問題を回避するには、メソッドに少なくとも1つ以上のreturnステートメントが必要です。
Try-finallyブロックにreturnステートメントを追加していて、catchブロックがない場合は問題ありません。ここに異常なコードパスのケースはありません。
Tryブロックにreturnステートメントを追加し、catchブロックがある場合、catchブロックまたはメソッドの最後にreturnを追加できます。
Tryブロックにreturnステートメントを追加し、catchブロックとfinallyブロックがある場合、catchブロックまたはメソッドの最後にreturnを追加できます。また、finallyブロックにreturnを追加することもできます。 Eclipseを使用している場合、上記のメソッド定義を使用して抑制できる警告が生成されます-
@SuppressWarnings("finally")