在Java中的Rethrowexception

关于在Java中重新抛出exception,我有一个非常简单的问题。

这是代码片段:

public static void main(String[] args) throws FileNotFoundException { try { FileReader reader = new FileReader("java.pdf"); } catch (FileNotFoundException ex) { throw ex; } } public static void main(String[] args) throws FileNotFoundException { FileReader reader = new FileReader("java.pdf"); } 

为什么我们需要在第一个版本中重新抛出ex ,而第二个版本看起来更优雅? 什么可能是好处,哪个版本比另一个更受欢迎?

你是对的。 第二个版本更好。 而且第一个版本没有任何意义。 除了exception的堆栈跟踪将是“错误的”之外,它也是如此。

“重新抛出”exception有以下原因:

  1. 如果你以前有事情要做。
  2. 如果捕获一种类型的exception并抛出其他类型的exception:

例:

 try { // do something } catch (IOException ioe) { throw new IllegalStateException(ioe); } 

在给出的示例中,重新抛出Exception没有任何意义。

如果捕获然后重新抛出exception的方法需要在看到Exception时采取一些额外的操作,并且还希望将Exception传播到调用者,这样调用者可以看到Exception ,这样做很有用。采取一些行动。

如果我想在catch块中执行其他操作,我只会捕获/重新抛出exception(而不是仅仅抛出它) – 例如,在重新抛出之前编写一个日志语句。

除了想要在退出之前对exception做一些事情 – 比如日志记录,另一次你会做这样的事情,如果你想把它包装成一个不同的例外,比如:

 try { FileReader reader = new FileReader("java.pdf"); } catch (FileNotFoundException ex) { throw new ServletException(ex); } 

问题是为什么你认为你需要重新抛出exception。 Eclipse是否建议使用try-catch ? 在实践中,我们很少重新抛出相同的exception,但经常捕获一个并抛出另一个包装第一个exception,特别是如果未选中包装器exception。 只要您有声明已检查exception的调用,就会发生这种情况,但是您编写这些调用的方法并未声明这些exception:

 public int findId(String name) { try { return db.select("select id from person where name=?", name); } catch (SQLException e) { throw new RuntimeException(e); } } 

执行流程在throw语句之后立即停止; 任何后续声明都不会被执行。 检查最近的封闭try块以查看它是否具有与exception类型匹配的catch语句。

如果找到匹配项,则控制权转移到该语句。 如果没有,则检查下一个封闭的try语句,依此类推。 如果未找到匹配的catch ,则默认exception处理程序将暂停程序并打印堆栈跟踪。

如果该方法能够导致它无法处理的exception,则必须指定此行为,以便该方法的调用者可以防范该exception。

可以通过在方法声明中包含throws子句来做到这一点。 throws子句列出了方法可能抛出的exception类型。 这对于所有exception都是必需的,除了ErrorRuntimeException类型或它们的任何子类。 必须在throws子句中声明方法可以抛出的所有其他exception。 如果不是,则会产生编译时错误。

两个版本都将输出相同的堆栈跟踪

没有尝试/捕获

 import java.io.FileNotFoundException; import java.io.FileReader; public class Test { public static void main(String[] args) throws FileNotFoundException { // try { FileReader reader = new FileReader("java.pdf"); // } catch (FileNotFoundException ex) { // throw ex; // } } } 

将输出

 Exception in thread "main" java.io.FileNotFoundException: java.pdf (The system cannot find the file specified) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.(FileInputStream.java:138) at java.io.FileInputStream.(FileInputStream.java:93) at java.io.FileReader.(FileReader.java:58) at Test.main(Test.java:7) 

与try / catch / throw相同的exception

 import java.io.FileNotFoundException; import java.io.FileReader; public class Test { public static void main(String[] args) throws FileNotFoundException { try { FileReader reader = new FileReader("java.pdf"); } catch (FileNotFoundException ex) { throw ex; } } } 

将输出与以前完全相同

 Exception in thread "main" java.io.FileNotFoundException: java.pdf (The system cannot find the file specified) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.(FileInputStream.java:138) at java.io.FileInputStream.(FileInputStream.java:93) at java.io.FileReader.(FileReader.java:58) at Test.main(Test.java:7) 

try / catch / throw换行exception

一种可取的方法是抛出自己的exception。 如果你想提供根本原因的详细信息(可能是想要或不想要的话),请将你刚刚捕到的exception包装起来

 import java.io.FileNotFoundException; import java.io.FileReader; public class Test { public static void main(String[] args) { try { FileReader reader = new FileReader("java.pdf"); } catch (FileNotFoundException ex) { throw new RuntimeException("Error while doing my process", ex); } } } 

您可以清楚地看到顶级问题(我的进程未完成),以及导致它的根本原因(找不到java.pdf文件)

 Exception in thread "main" java.lang.RuntimeException: Error while doing my process at Test.main(Test.java:9) Caused by: java.io.FileNotFoundException: java.pdf (The system cannot find the file specified) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.(FileInputStream.java:138) at java.io.FileInputStream.(FileInputStream.java:93) at java.io.FileReader.(FileReader.java:58) at Test.main(Test.java:7)