【问题标题】:java lazy code after return using try - finally使用try-finally返回后的java惰性代码
【发布时间】:2013-09-11 12:24:02
【问题描述】:

我发现使用 finally 有代码“返回后”的可能性,这里有一些例子:

int foo() {
    BufferedReader br = ...;
    try {
        // cca 20 lines with 4 returns in different if-else clauses etc
        //example:
        if(something) {
            return 0;
        } else {
            return 1;
        }
    } finally {
        br.close();
    }
}

作为(在我看来更懒惰)替代:

int foo() {
    BufferedReader br = ...;
    int toReturn;

    // cca 20 lines with 4 ASSIGMENTS in different if-else clauses etc
    //example:
    if(something) {
        toReturn = 0;
    } else {
        toReturn = 1;
    }

    br.close();
    return toReturn;
}

所以,问题是,哪个更快,更具可读性,是的,在这种情况下,我真的要关闭一个 BufferedReader,所以是 try-finnaly 还是我用错了?

【问题讨论】:

    标签: java return try-finally


    【解决方案1】:

    如果不使用try/catch/finally,如果抛出异常,您的BufferedReader 将无法正确关闭,从而导致内存泄漏、潜在的不需要的文件锁定...

    使用finally,您的BufferedReader 将被关闭,即使在处理try 块时抛出异常。

    但是由于您的 BufferedReader 实例化也可能引发异常,您应该将其包含在您的 try 块中:

    BufferedReader br = null;
    try {
        br = ...;
        // do your stuff
    }
    catch (Exception e) {
        // handle exception
    }
    finally {
        if(br != null)
            br.close();
    }
    

    如果您使用的是 Java 7 或更高版本,请使用优雅的 Try-with-resources,如 Arnaud 所述。

    【讨论】:

      【解决方案2】:

      如果存在exceptionthrows,则您的代码都会失败,因为第一种情况您没有捕获exception,第二种情况没有处理exception 的证据。

      finally 将在这里执行任何方式。

      如果您的BufferedReader 通过文件读取获取输入,则在没有找到哪个文件的情况下,两种方式都没有用。

      【讨论】:

        【解决方案3】:

        第二个实际上是不可接受的。出现异常时不会关闭缓冲区。

        我建议您使用 try-with-resources 语句(用于此目的):

        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
            //do what you want with the buffer. It will automatically be closed.
            return;
        }
        

        The try-with-resources Statement

        【讨论】:

        • 仅适用于 java 7 及更高版本。
        【解决方案4】:

        我用错了吗?

        是的,你是。如果说something 是一个方法调用并抛出异常,那么你的br 永远不会关闭。虽然 finally 确保在任何情况下它都会被执行*

        `* - 在某些情况下你可以避免 finally 子句的执行

        【讨论】:

          猜你喜欢
          • 2014-04-27
          • 2011-05-10
          • 1970-01-01
          • 2018-11-05
          • 2012-02-10
          • 2017-07-20
          • 1970-01-01
          • 2011-11-17
          • 2016-03-28
          相关资源
          最近更新 更多