【问题标题】:Order of execution in try/catch/finally block with compound return statement in try blocktry/catch/finally 块中的执行顺序与 try 块中的复合 return 语句
【发布时间】:2019-04-25 01:17:30
【问题描述】:

所以,我遇到了这段代码,想知道复合 return 语句是否会失败,因为 finally 块是在 return 语句执行之前执行的:

public DataObject processor(LinkedHashMap itemList)
{
    Extractor ex = DataExtractor.getExtractor();

    try{

        ex.open();

        return ex.processData(itemList);

    }catch(Exception e){

        /* error code */

    }finally{

        if(ex.isOpen()) ex.close();
    }
}

我的看法是执行 finally 块,关闭提取器,然后执行复合返回语句,使用关闭的提取器,这将导致错误。

问题:复合 return 语句是在 finally 块执行之前还是之后执行,导致尝试使用关闭的 Extractor 进行操作?

【问题讨论】:

  • finally 块总是最后运行
  • 我认为是先执行ex.processData(itemList),并保存返回值,然后执行finally子句,再执行return保存的值。
  • return foo();Object f = foo();return f;没有区别
  • @markspace 如果你在 try 块中返回一个变量名,那么如果你在 finally 块中修改并返回变量名,最后你会得到修改后的名称,所以你是对的。

标签: java


【解决方案1】:

复合return语句是在finally块执行之前还是之后执行?

答案是两者都

  • 假设您在该点之前没有遇到异常,ex.processData(itemList);finally 块之前被评估。

  • 实际的returnfinally 块之后执行

...导致尝试使用关闭的提取器进行操作?

这不会发生。


实现这一点的首选方法如下:

try (Extractor ex = DataExtractor.getExtractor().open()) {
    return ex.processData(itemList);
} catch(SpecificException e) {
    /* error code */
}

使用 Java 7+ 尝试使用资源,然后让其负责关闭 Extractor。并且(在大多数情况下)不要抓住Exception

【讨论】:

    【解决方案2】:
    private static int getInt() {
        int i = 0;
        try(FileInputStream in = new FileInputStream("FILE_PATH")) {
           i = 1;
           return i;
        } catch (Exception e) {
           e.printStackTrace();
        } finally {
           i = 10;
           return i;
        }
    }
    
    public static void main(String[] args) {
        System.out.println(getInt()); // print 10 rather than 1
    }
    

    方法只返回一次,并且顺序是固定的,所有操作变量都在方法栈中,return语句会在栈中取值然后返回,所以如果修改finally块中的值,方法总是会返回新值。

    【讨论】:

    • 以上代码,给出警告finally block does not complete normally,因为它预计不会从finally块返回reference
    • @Cchanchal - 正确。此示例中的代码/方法绝不应在实际应用程序中使用。但这里的重点是说明从finally 块内部返回时可能发生的反直觉 行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 2019-04-07
    • 1970-01-01
    • 2015-09-05
    相关资源
    最近更新 更多