web-dev-qa-db-ja.com

try、catch、最後にJavaでreturnはどのように機能しますか?

returntrycatchがどのように機能するかを正確に理解できません。

  • tryなしでfinallycatchがある場合、returnブロック内にtryを配置できます。
  • trycatchfinallyがある場合、returnブロックにtryを入れることはできません。
  • catchブロックがある場合、returntrycatchブロックの外側にfinallyを配置する必要があります。
  • catchブロックとthrow Exceptionを削除すると、returnブロック内にtryを配置できます。

正確にどのように機能しますか? returntryブロックに入れられないのはなぜですか?

trycatchfinallyを使用したコード

 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);
     }
 }
28
elvis

はい、わかりにくいです。

Javaでは、allvoid関数のプログラム制御パス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
}
38
Bathsheba

そして、もし私が試したなら、最後に、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つの実行パスがあります。

  1. final int i = foo()
  2. どちらか
    1. System.out.println("finally")
    2. _return i_
  3. または
    1. System.out.println(e)
    2. System.out.println("finally")
    3. _throw e_

fooによって例外がスローされない場合、パス(1、2)が使用されます。例外がスローされた場合、パス(1、3)が使用されます。どちらの場合でも、finallyブロックが実行される方法に注意してくださいbeforeメソッドが残されます。

10
Konrad Rudolph

最終的にブロックは、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ブロック内にあります。

6
pramesh

これは、例外処理が関係する場合の通常のプログラムフローです。コードに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")
0
user8235810