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建议的解决方案通常是一个坏主意。当然在生产代码中。