3

我有一个异常链,其中method1抛出一个异常method2,将异常抛出到main. 出于某种原因,编译器强制我处理错误,method2如果我不这样做,则将其标记为错误,表明这是一个已检查的异常。但是,当同样Exception的内容被进一步抛出时main,编译器允许我忽略它并且不显示任何错误。

中的原始异常method1是 a ParseException,已检查。但是该方法在头中有一个通用throws Exception子句,并且将相同的对象抛出给具有相同throws Exception子句的method2。这个异常何时以及如何失去被编译器检查/捕获的状态?

编辑澄清:

public void method1() throws Exception{
   // code that may generate ParseException
}

public void method2() throws Exception{
   method1(); //compiler error (if the throws clause is left out)
}

public static void main(String[] args){
   method2(); //ignored by compiler, even though the exception isn't caught or thrown or handled at all
}

编辑: 对不起大家,这个问题是基于一个错误......主要方法实际上有一个throws Exception我错过的子句。我已经删除了它,代码现在按预期运行。感谢所有的帮助!

4

4 回答 4

6

一个异常是否被检查完全取决于它是什么类型的异常:如果它是它的一个RuntimeException或它的子类,它不会被检查;否则,它是。(是的,它是 Java 库设计失败之一的RuntimeException子类,但不是最严重的。)Exception

编译器检查的是方法签名。所以抛出的实际异常是无关紧要的(为此)。如果方法说throws Exception,那么你必须Exception在你的方法中捕获或声明方法throws Exception。方法应始终使用最窄的 throws子句——例如not throws Exception but throws ParseException

(我说“不相关(为此目的)”,因为,当然,编译器会做的另一件事是检查您是否不会抛出您的throws子句未涵盖的已检查异常。)

编辑您在编辑中添加的代码将无法编译:1.它正在调用没有实例的实例方法,并且2.main需要声明它 throws Exception

这段代码解决了其他问题,并且(正确地)演示了main需要throws Exception子句:

public class CheckTest
{
    public static final void main(String[] params)
    {
        new CheckTest().method2();
    }

    public void method1() throws Exception{
        throw new java.text.ParseException("foo", 2);
    }

    public void method2() throws Exception{
        this.method1();
    }
}

结果:

CheckTest.java:27: unreported exception java.lang.Exception; must be caught or declared to be thrown

                new CheckTest().method2();
                                       ^
1 error
于 2010-05-06T14:38:17.297 回答
3

已检查的异常不会停止成为已检查的异常。您可以将已检查异常变为未检查异常的方法是将其包装在 RuntimeException 类型中并重新抛出它。

于 2010-05-06T14:35:33.340 回答
2

在您的情况下,它将Exception一直到调用堆栈的根。如果一个方法被声明为抛出Exception(这些方法很少应该这样做),调用方法要么必须说它也抛出Exception,要么捕获它并处理它。

编辑至于已编辑的 OP 中的示例,它不会编译。但是,如果您不想处理它,可以声明mainthrow 。Exception

于 2010-05-06T14:38:39.287 回答
0

您的编译器是否有可能没有抱怨该问题,main()因为它遇到了问题method2()并在那时停止检查语法?两者都应该是错误的。您是否修复了呼叫method2()并进行了干净的编译?

于 2010-05-06T14:38:43.577 回答