我知道 Java 异常的开销已经在 SO 上被彻底解决了,但我没有找到任何可以解决我的情况的东西。我有一个 Future,它在调用 get() 时可能会抛出包含任意数量的特定于应用程序的异常的 ExecutionException。我想知道使用更好看的 try-catch block 而不是丑陋的 if-instanceof-then-cast 模式是否有显着的开销。例如,它可能看起来像这样:
private Response handleException(ExecutionException e) throws MyApplicationException {
try {
throw e.getCause();
} catch (ApplicationException1 e1) {
// known error
throw MyApplicationException.convert(e1);
} catch (ApplicationException2 e2) {
// create error response
return new Response(e2);
} catch (Throwable t) {
// unknown error
throw new RuntimeException(t);
}
}
private Response handleException2(ExecutionException e) throws MyApplicationException {
Throwable cause = e.getCause();
if (cause instanceof ApplicationException1) {
ApplicationException1 e1 = (ApplicationException1) cause;
throw MyApplicationException.convert(e1);
} else if (cause instanceof ApplicationException2) {
ApplicationException2 e2 = (ApplicationException2) cause;
return new Response(e2);
} else {
throw new RuntimeException(cause);
}
}
我的理论是不应该有大量的开销,因为
- 异常和堆栈跟踪已经构建。
- 无论如何,我都在两种方法中对异常对象执行反射。
- 异常会被立即捕获并且不会传播。
最佳答案
就风格而言,我通常建议不要对常规控制流使用异常处理程序。不过,我可以在这里看到使用它的论点,因为 Future
的设计要求您“打开”原始异常。
重新抛出一个异常应该比抛出一个新异常的成本要低得多,因为堆栈跟踪已经被填充。您的第一种方法可能仍有更多的开销,但如果您的应用程序抛出如此多的异常以至于影响变得明显,那么您可能会遇到更大的问题。
如果您真的很担心,获得有意义答案的唯一方法是您自己衡量差异。但是,同样,只有在异常(exception) 情况下才应抛出异常;它们在设计上应该不常见。即使将异常处理的成本加倍,成本也只是 2n 而不是 n。如果您抛出如此多的异常以致您的应用程序的性能受到明显影响,那么简单的两个因素可能不会成败。因此,请使用您认为更具可读性的样式。
关于java - 重新抛出 Java 异常与使用 instanceof/cast 的开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23348950/