我有一个关于在Java中重新抛出异常的非常简单的问题。
以下是代码段:
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
而第二个版本看起来更优雅?什么可能是好处,哪个版本比另一个更受欢迎?
答案 0 :(得分:15)
你是对的。第二个版本更好。而且第一个版本没有任何意义。除了异常的堆栈跟踪“错误”之外,它也是一样的。
“重新抛出”例外有以下原因:
示例:
try {
// do something
} catch (IOException ioe) {
throw new IllegalStateException(ioe);
}
答案 1 :(得分:8)
在给出的示例中,重新抛出Exception
没有任何意义。
如果捕获然后重新抛出异常的方法需要在看到Exception
时采取一些额外的操作,并希望{{1},那么执行此可以非常有用传播给调用者,以便调用者可以看到Exception
并执行某些操作。
答案 2 :(得分:7)
如果我想在catch块中执行其他操作,我只会捕获/重新抛出异常(而不是仅仅抛出它) - 例如,在重新抛出之前编写一个日志语句。
答案 3 :(得分:3)
除了想要在退出之前对异常做一些事情 - 比如日志记录,另一次你会做这样的事情就是如果你想把它包装成一个不同的例外,比如:
try {
FileReader reader = new FileReader("java.pdf");
} catch (FileNotFoundException ex) {
throw new ServletException(ex);
}
答案 4 :(得分:2)
问题是您认为需要重新抛出异常的原因。 Eclipse是否建议使用try-catch
?在实践中,我们很少重新抛出相同的异常,但经常捕获一个并抛出另一个包装第一个异常,特别是如果未选中包装器异常。只要您发出声明已检查异常的调用,就会发生这种情况,但是您编写这些调用的方法并未声明这些异常:
public int findId(String name) {
try {
return db.select("select id from person where name=?", name);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
答案 5 :(得分:1)
执行流程在throw
语句后立即停止;任何后续陈述都不会被执行。检查最近的封闭try
块以查看它是否具有与异常类型匹配的catch
语句。
如果找到匹配项,则控制权转移到该语句。如果没有,则检查下一个封闭的try
语句,依此类推。如果未找到匹配的catch
,则默认异常处理程序将暂停程序并打印堆栈跟踪。
如果该方法能够导致它无法处理的异常,则必须指定此行为,以便该方法的调用者可以防范该异常。
可以通过在方法声明中包含throws
子句来实现此目的。 throws
子句列出了方法可能抛出的异常类型。这对于所有异常都是必需的,除了Error
或RuntimeException
类型或其任何子类的异常。方法可以抛出的所有其他异常必须在throws
子句中声明。如果不是,则会产生编译时错误。
答案 6 :(得分:1)
两个版本都将输出相同的堆栈跟踪
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.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
at Test.main(Test.java:7)
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.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
at Test.main(Test.java:7)
一种可行的方法是抛出自己的异常。 如果您想提供根本原因的详细信息(可能是想要或不想要的话),请将刚捕获的异常包装起来
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.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
at Test.main(Test.java:7)