10

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

4

7 回答 7

15

你说的对。第二个版本更好。此外,第一个版本没有任何意义。除了异常的堆栈跟踪将是“错误的”之外,它的作用相同。

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

  1. 如果你之前有事要做。
  2. 如果您捕获一种类型的异常并抛出另一种类型的异常:

例子:

try {
   // do something
} catch (IOException ioe) {
    throw new IllegalStateException(ioe);
}
于 2012-08-15T16:01:25.543 回答
9

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

如果捕获然后重新抛出异常的方法需要在看到 时采取一些额外的操作,并且还希望将传播给调用者,以便调用者可以看到并采取一些操作,那么这样做很有用.ExceptionExceptionException

于 2012-08-15T15:59:58.710 回答
8

如果我想在 catch 块中做其他事情,我只会捕获/重新抛出一个异常(而不是仅仅抛出它)——例如,在重新抛出之前编写一个日志语句。

于 2012-08-15T15:59:38.497 回答
3

除了想在退出之前对异常做一些事情——比如日志记录,另外一次你会做类似的事情是如果你想把它包装成一个不同的异常,比如:

try {
    FileReader reader = new FileReader("java.pdf");
} catch (FileNotFoundException ex) {
    throw new ServletException(ex);
}
于 2012-08-15T16:04:11.910 回答
3

问题是为什么你认为你需要重新抛出异常。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);
  }
}
于 2012-08-15T16:08:54.003 回答
2

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

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

如果该方法能够导致它无法处理的异常,则它必须指定此行为,以便该方法的调用者可以保护自己免受该异常的影响。

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

于 2017-01-05T17:23:55.977 回答
2

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

没有尝试/捕获

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)
于 2017-03-30T09:35:16.747 回答