重新检查异常

Bar*_*lom 2 java error-handling transactions exception-handling exception

public void foo() {
 begin();
 try {
  ...
  commit();
 } catch (Exception e) {
  rollback();
  throw e;
 }
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,有一个错误,因为foo没有throws Exception.添加它不会使方法的可用性也很好.

最好的方法是什么?如果在没有真正"处理"错误的情况下发生错误,您如何做某事?

T.J*_*der 6

至少会想到两种方法,这些方法通常会根据您的要求进行组合foo:

1.仅捕获并重新抛出相关的例外情况

主流中的代码只能抛出很多例外(可能主要是SqlExceptions).所以只抓住并重新抛出那些,并声明你正在这样做.更重要的是,重新抛出你实际上没有处理的那些(在简化的示例代码中,你没有处理任何代码,但你的真实代码可能更微妙).

请注意,一些例外可能是运行时异常,因此您可能希望将此与下面的内容结合起来.

2.根本不要抓住例外

像这样:

// Signature changes to include any exceptions that really can be thrown
public void foo() throws XYZException, ABCException {
 // A flag indicating that the commit succeeded
 boolean done = false;

 begin();
 try {
  // Don't have any `return` statements in here (or if you do,
  // set `done` to `true` first)

  ...
  commit();
  done = true; // Commit didn't throw an exception, we're done
 } finally {
  // finally clause always happens regardless
  if (!done) {
    // We must be processing an exception; rollback
    try {
      rollback();
    } catch (Exception e) {
      // quash it (e.g., leave this block empty), we don't want
      // to mask the real exception by throwing a different one
    }
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

当然,您的签名需要包含可能在主流中抛出的任何异常,但如果我正确理解您,那就是您要做的事情.

同样,您可能会将这两种方法结合起来,因为您可能希望处理一些异常而不是其他异常.


Pet*_*rey 5

从Java 8开始,我们使用

/**
 * Cast a CheckedException as an unchecked one.
 *
 * @param throwable to cast
 * @param <T> the type of the Throwable
 * @return this method will never return a Throwable instance, it will just throw it.
 * @throws T the throwable as an unchecked throwable
 */
@SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
    throw (T) throwable; // rely on vacuous cast
}
Run Code Online (Sandbox Code Playgroud)

您可以重新抛出已检查的异常,但是只能避免编译器进行已检查的异常验证。

public void foo() throws MyCheckedException {
 begin();
 try {
  ...
  commit();
 } catch (Exception e) {
  rollback();
  // same as throwing an exception without the compiler knowing.
  Thread.currentThread().stop(e); 
 }
}
Run Code Online (Sandbox Code Playgroud)

在使用stop()之前,您应该阅读http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

Thread.currentThread()。stop(e)..在行为上与Java的throw操作相同,但是绕过了编译器试图保证调用方法已声明所有可能抛出的已检查异常的尝试: