如何在Java中实现`finally` for error case

时间:2010-12-09 22:55:50

标签: java exception-handling

如果发生任何错误,我需要触发一些代码。基本上我需要一个finally块,只有在异常情况下才会执行。我会这样实现它:

HttpURLConnection post(URL url, byte[] body) throws IOException {
    HttpURLConnection connection = url.openConnection();
    try {
        OutputStream out = connection.getOutputStream();
        try {
            out.write(body);
        } finally {
            out.close();
        }
        return connection;
    } catch (Throwable t) {
        connection.disconnect();
        throw t;
    }
}

看起来很好 - 除了它不会编译:我的函数不能抛出Throwable

我可以重写:

    } catch (RuntimeException e) {
        connection.disconnect();
        throw e;
    } catch (IOException e) {
        connection.disconnect();
        throw e;
    }

但即便如此,我仍然是a)错过所有错误,并且b)必须在我更改实现时抛出不同类型的异常时修复此代码。

是否可以一般性地处理这个问题?

3 个答案:

答案 0 :(得分:11)

你可以使用finally块,并添加一个标志来表示成功。

bool success = false;
try {
    //your code
    success = true;
    return retVal;
} finally {
    if (!success) {
        //clean up
    }
}

答案 1 :(得分:3)

Throwable有两个子类ErrorExceptionError的Javadocs说:

  

错误是Throwable的子类   表示严重问题a   合理的申请不应该尝试   赶上。大多数此类错误都是   异常情况。 ThreadDeath   错误,虽然是“正常”的条件,但是   也是一个Error的子类,因为大多数   应用程序不应该尝试捕获   它

因此,除非这是一个真正不同寻常的情节,否则你可以专注于Exception

catch (IOException e) {
    connection.disconnect();
    throw e;
}
catch (RuntimeException e) {
    connection.disconnect();
    throw e;
}
catch (Exception e) {
    connection.disconnect();
    throw new IOException(e);
}

答案 2 :(得分:-1)

除非我弄错了,否则异常不需要finally块来停止执行并执行您需要的操作,例如清理或缓解错误。

try {
  // Do some work! 
  // Fail
} catch (IOException e) {
  // Clean up, alert user, expected error
} catch (Exception e) {
  // Not so much expected, but lets try to handle this
}

错误应来自您实施的类和方法,这些基本上都是您的想法。考虑执行流程和错误传播。如果上面的方法没有捕获到特定的异常,那么调用它的任何东西都会看到异常。

Throwable只是一个带有子类的顶级类。例外情况通常都是一个问题。并记住,您还可以实现自己的异常来处理任务。