在 Java 中,如何尝试、捕获、最终返回工作?

2022-09-01 09:36:42

我无法确切地理解在 , .returntrycatch

  • 如果我有并且没有,我可以放在块内。tryfinallycatchreturntry
  • 如果我有 , , , ,我就不能放进去。trycatchfinallyreturntry
  • 如果我有一个块,我必须把,,块的外部。catchreturntrycatchfinally
  • 如果我删除块和,我可以把块放进去。catchthrow Exceptionreturntry

它们究竟是如何工作的?为什么我不能把 放在块里?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;
 }

带 的代码,不带tryfinallycatch

 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 中,非函数的所有程序控制路径必须以 结尾,否则将引发异常。这是很好和简单的规则。voidreturn

但是,在令人憎恶的情况下,Java允许您在块中放置额外的内容,这会覆盖以前遇到的任何内容:returnfinallyreturn

try {
    return foo; // This is evaluated...
} finally {
    return bar; // ...and so is this one, and the previous `return` is discarded
}

答案 2

最后,即使我们在 catch 块中捕获了异常,或者甚至我们的 try 块也始终执行。

所以什么时候做块最终将在流中执行...

如果我们在 try/catch 块中有 return 语句,那么在执行 return 语句之前,最终将执行块(如关闭连接或 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;
  }
}

但是,如果您在 finally 语句中有 return 语句,那么它将覆盖 try 或 catch 块内的 return 语句