在Java中的Rethrow异常

时间:2012-08-15 15:58:02

标签: java exception exception-handling

我有一个关于在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而第二个版本看起来更优雅?什么可能是好处,哪个版本比另一个更受欢迎?

7 个答案:

答案 0 :(得分:15)

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

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

  1. 如果你以前有事情要做。
  2. 如果您捕获一种类型的异常并抛出其他类型的异常:
  3. 示例:

    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子句列出了方法可能抛出的异常类型。这对于所有异常都是必需的,除了ErrorRuntimeException类型或其任何子类的异常。方法可以抛出的所有其他异常必须在throws子句中声明。如果不是,则会产生编译时错误。

答案 6 :(得分:1)

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

没有try / catch

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)

与try / catch / throw相同的异常

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)

try / catch / throw wrap 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.<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)