在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有以下原因:
- 如果你以前有事情要做。
- 如果捕获一种类型的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都是必需的,除了Error
或RuntimeException
类型或它们的任何子类。 必须在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)
- 文件存在时具有所有权限的FileNotFoundException
- 本地变量可能尚未初始化 – 检测方法中未经检查的exception抛出
- 将面板添加到框架时获取空指针exception
- 是否可以使用exception而不是详细的空检查?
- 不能使用try / catch块处理java未经检查的exception?
- Swing JTabbedPane在填充时抛出IndexOutOfBoundsException
- org.openqa.selenium.UnhandledAlertException:意外警报打开
- 我应该在throws规范中声明未经检查的exception吗?
- MediaSession finishBroadcast()exception