简体   繁体   English

返回如何在try,catch,最后在Java中工作?

[英]How does return work in try, catch, finally in Java?

I can't understand exactly how return works in try , catch . 我无法准确理解returntrycatch是如何工作的。

  • If I have try and finally without catch , I can put return inside the try block. 如果我try并且finally没有catch ,我可以在try块中return
  • If I have try , catch , finally , I can't put return in the try block. 如果我有trycatchfinally ,我不能把returntry块。
  • If I have a catch block, I must put the return outside of the try , catch , finally blocks. 如果我有一个catch块,我必须把try returntrycatchfinally块之外。
  • If I delete the catch block and throw Exception , I can put the return inside the try block. 如果我删除catch块并throw Exception ,我可以将return放在try块中。

How do they work exactly? 它们如何正常工作? Why I can't put the return in the try block? 为什么我不能把return放在try块中?

Code with try , catch , finally 代码与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;
 }

Code with try , finally without catch try finally代码, 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);
     }
 }

Yes, it's confusing. 是的,这令人困惑。

In Java, all program control paths of a non- void function must finish with a return , or throw an exception. 在Java中,非void函数的所有程序控制路径必须return结束,否则抛出异常。 That's the rule put nice and simply. 这就是规则很简单。

But, in an abomination, Java allows you to put an extra return in a finally block, which overrides any previously encountered return : 但是,在令人厌恶的情况下,Java允许您在finally块中添加额外的 return ,这会覆盖以前遇到的任何return

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

And if I have try, catch, finally I can't put return in the try block. 如果我尝试了,赶上,最后我不能把它放在try块中。

You absolutely can. 你绝对可以。 You just need to make sure that every control path in your method is terminated properly. 您只需要确保方法中的每个控制路径都正确终止。 By that I mean: every execution path through your method either ends in a return , or in a throw . 我的意思是:通过您的方法的每个执行路径都以returnthrow

For instance, the following works: 例如,以下工作:

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");
    }
}

Here, you've got two possible execution paths: 在这里,您有两个可能的执行路径:

  1. final int i = foo()
  2. either
    1. System.out.println("finally")
    2. return i
  3. or 要么
    1. System.out.println(e)
    2. System.out.println("finally")
    3. throw e

Path (1, 2) is taken if no exception is thrown by foo . 如果foo没有抛出异常,则采用路径(1,2)。 Path (1, 3) is taken if an exception is thrown. 如果抛出异常,则采用路径(1,3)。 Note how, in both cases, the finally block is executed before the method is left. 请注意,在两种情况下,如何在方法离开之前执行finally块。

Finally block will always execute even if we caught the exception in catch block or even our try block executed as expected. 即使我们在catch块捕获异常,甚至我们的try块按预期执行, 最后块也将始终执行。

so when does finally block will be execute with in the flow... 所以什么时候最终块将在流程中执行...

if we have return statement inside the try/catch block then before executing the return statement finally block will be executed (like as for closing the connection or I/O) 如果我们在try / catch块中return语句,那么在执行return语句之前, finally块将被执行(就像关闭连接或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;
  }
}

but if you have return statement inside the finally statement then it will override the return statement inside the try or catch block. 但是如果你在finally语句中return语句,那么它将覆盖 try或catch块中的return语句

This is normal program flow when exception handling is involved. 当涉及异常处理时,这是正常的程序流程。 Having catch block in the code creates a case where code path can directly jump in to catch block. 在代码中有catch块会创建一个代码路径可以直接跳转到catch块的情况。 This defeats the mandate of having return statement in the method which returns something. 这违背了在返回某些东西的方法中使用return语句的任务。 It is possible that return statement may not get executed if exception occurs, hence compiler throws error. 如果发生异常,可能无法执行return语句,因此编译器会抛出错误。 So to avoid this issue, you need at least 1 more return statement in a method. 因此,要避免此问题,您需要在方法中至少再使用一个return语句。

If you have added a return statement in try-finally block and you dont have catch block, it is ok. 如果你在try-finally块中添加了一个return语句而你没有catch块,那就没问题了。 There is no case of abnormal code path here. 这里没有异常代码路径的情况。

If you have added a return statement in try block and you have catch block, then you can either add return in catch block or at the end of method. 如果在try块中添加了一个return语句并且你有catch块,那么你可以在catch块中或在方法结束时添加return。

If you have added a return statement in try block and you have catch block and finally block, then you can either add return in catch block or at the end of method. 如果你在try块中添加了一个return语句并且你有catch块并且最后阻塞了,那么你可以在catch块中或在方法结束时添加return。 You can also choose to add return in finally block. 您还可以选择在finally块中添加return。 If you are using eclipse, it will generate a warning which can be suppressed using below above method definition - 如果您正在使用eclipse,它将生成一个警告,可以使用上面的方法定义来抑制 -

@SuppressWarnings("finally")

I think this is what you're asking: 我想这就是你要问的:

And if I have try, catch, finally I can't put return in the try block. 如果我尝试了,赶上,最后我不能把它放在try块中。

So if you add a catch block, you can't put a return in the try block. 因此,如果添加catch块,则无法在try块中添加return

The problem is that if you add a catch then control drops through and you need a return at the end of the method or it's a syntax error. 问题是,如果你添加一个catch然后控件就会通过 ,你需要在方法结束时return ,否则就是语法错误。 I haven't tested this but I assume you could put a return in the try block, but you would also have to add one inside the catch or at then end of the method as you have now. 我没有测试过这个但是我假设你可以try块中放一个return ,但是你还必须在catch添加一个或者在你现在的方法末尾添加一个。

In the second example, if the checked exception occurs then it hands over to calling a method. 在第二个示例中,如果发生检查的异常,则将其移交给调用方法。

In the first example, if the checked exception occurs then it handles in the same method, as catch block take the responsibility to handle the exception. 在第一个示例中,如果发生检查的异常,则它在同一方法中处理,因为catch块负责处理异常。

if you write return statement in catch block then it works. 如果你在catch块中写return语句那么它可以工作。
ie,

try{  
    return ..  
}catch(Exception e){  
    return ..  
}finally{  
}

But it is not good programming practice. 但这不是一个好的编程实践。

使用void函数以外的公共函数时,应返回一些内容,否则函数不会返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM