Java 无法重新播放异常

Java 无法重新播放异常,java,exception,Java,Exception,我创建了一个如下所示的类,我想知道为什么我不能简单地捕获并重新抛出一个异常: public class TestClass implements Runnable { @Override public void run() { try{ FileInputStream inStream = new FileInputStream(""); }catch(Exception e){

我创建了一个如下所示的类,我想知道为什么我不能简单地捕获并重新抛出一个异常:

public class TestClass implements Runnable {
    @Override
    public void run() {
        try{
            FileInputStream inStream = new FileInputStream("");
        }catch(Exception e){
            throw e;
        }
    }
}
Eclipse显示编译错误:“未处理的异常类型FileNotFoundException” 并建议进行以下修复,出于某种原因,修复效果良好:

@Override
public void run() {
    try{
        FileInputStream istream = new FileInputStream("");
    }catch(Exception e){
        try {
            throw e;
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}
这里发生了什么?

的构造函数声明抛出一个选中的异常。根据所谓的方法,这意味着抛出这种类型异常的方法必须要么捕获它(不包括重新引用它),要么在接口中声明它。因为您的
run
方法没有声明它(并且您不能声明,因为它重写了
Runnable\run()
),所以您会得到错误

如果捕获异常并用print语句将其吞下,则满足“catch”要求,错误消失。如果抛出一个扩展了
RuntimeException
的异常,则这是一个未经检查的异常,catch或specify要求不适用

有趣的是,Eclipse编译器所做的流分析有点过于激进,这导致了令人困惑且可能不完整的错误消息

未处理的异常类型FileNotFoundException

例如,如果
try
块中有以下代码,则此类型特异性将不完整:

Class.forName("foo");
FileInputStream inStream = new FileInputStream("");

然后您仍然会得到一个关于
FileInputStream
的错误,即使
forName
也会导致一个不同类型的未经处理的已检查异常(
ClassNotFoundException
)。

因为接口中的run()方法未声明引发异常。异常是一个已检查异常,因此,任何抛出它的方法都必须在
throws
子句中声明它。您不能从
Runnable.run()
中抛出它,因为接口没有声明可能会抛出该异常。@khelwood谢谢,这很有意义。我想知道为什么抛出一个不同的异常,比如NullPointerException,编译起来很好。但现在我想知道为什么原始捕获中的额外try-catch似乎有效?@khelwood澄清了我的上述评论,因为我无法再编辑它了:这就回答了为什么*抛出不同的异常编译效果很好。如果您想创建一个答案,我接受它。值得注意的是,Eclipse建议的解决方案通常是一个坏主意。当然在生产代码中。