Java 这是不是“尝试…抓住…最后”多余?
这与省略catch子句有什么不同吗Java 这是不是“尝试…抓住…最后”多余?,java,exception-handling,control-flow,try-catch-finally,Java,Exception Handling,Control Flow,Try Catch Finally,这与省略catch子句有什么不同吗 public Foo doDangerousStuff() throws Exception { try { dangerousMethod(); return new Foo(); } catch (Exception e) { throw e; } finally { mustBeCalledAfterDangerousMethod(); } } [编辑]要
public Foo doDangerousStuff() throws Exception {
try {
dangerousMethod();
return new Foo();
} catch (Exception e) {
throw e;
} finally {
mustBeCalledAfterDangerousMethod();
}
}
[编辑]要清除混淆,是的,
catch
块除了重新抛出异常外,什么也不做。我想知道当调用finally
块时,这是否会导致某种不同的排序(假设抛出的异常被调用方捕获),但从我从thusfar的答案推断,情况并非如此。你是对的,这是一样的。甚至stacktrace也会出现:)
但是,如果将异常包装到某个更高级别的异常中,则可能会使用类似的代码。如果代码看起来和前面所说的一模一样,那就毫无意义了。它们是一样的。我会使用第二个版本。是的。因为您的方法已经抛出了“异常”,所以您不需要捕获它并重新抛出它。除非您想执行@Dave提到的操作。当您抛出catch子句中捕获的异常时,除了再次抛出它之外,其他什么都不做,是的,这两个代码将执行相同的操作。尽管这两个源代码表示相同的执行序列,但它们将产生不同的字节码。例如,第一个例程将有一个异常表,而第二个例程则没有。在没有插装的情况下,它们的字节码在执行期间将具有相同的效果。如果字节码在编译后插入指令,或者捕获的异常类型在执行期间类文件不可用,则这些方法的行为可能会有所不同。我的直觉告诉我它们是相同的;但是,因此,第一个是多余的,除非您想在抛出之前记录一些特定的内容(例如类名);或者抛出一个自定义异常。第一个异常也可能是IDE自动生成的catch子句,该子句从未被删除,即使该方法被声明为抛出相同的异常。但正如答案中所述,两者都做同样的事情。虽然迈克尔的答案很简单,但这一条提供了有趣的细节。你有什么链接可以让我阅读更多关于Java异常表生成的信息吗?JVM规范()是一个很好的起点。链接部分提供了通过编译各种形式的
try
语句生成的字节码结构的详细信息。
public Foo doDangerousStuff() throws Exception {
try {
dangerousMethod();
return new Foo();
} finally {
mustBeCalledAfterDangerousMethod();
}
}