0

当我编译以下代码时,一切正常,输出如预期:

class Propogate {
    public static void main(String[] args) {
        Propogate obj = new Propogate();
        try {
            obj.reverse("");
        } catch (IllegalArgumentException e) {
            System.out.println(e);
        } finally {
            System.out.println("That's all folks");
        }
    }
    String reverse(String s) {
        if(s.length() == 00) {
            throw new IllegalArgumentException();
        }
        String reversed = "";
        for(int i=s.length() - 1; i >= 0; --i) {
            reversed += s.charAt(i);
        }
        return reversed;
    }
}

节目结果:

java.lang.IllegalArgumentException
That's all folks

但是,当我运行完全相同的代码但将异常类型从

IllegalArgumentException to plain old exception all I get is:Propogate.java:14: error:    
unreported exception Exception; must be caught or declared to be thrown
                        throw new Exception();
                    ^
1 error

我无法使用 try / catch 语句处理的父类型 Exception() 有什么特别之处?为什么 IllegalArgumentException() 允许我用 try / catch 语句处理它就好了。这些是一个晚上因害怕失败而保持清醒的想法,不,只是参加 SCJP 考试。

4

4 回答 4

6

抛出不是子类的异常的方法RuntimeException必须声明它抛出了那个Exception。你必须写

String reverse(String s) throws Exception {

如果你要扔掉Exception它。一旦你这样做了,你就可以正常地用 try/catch 来捕捉它。

于 2013-12-12T00:40:55.117 回答
1

IllegalArgumentExceptions 是未经检查的异常,因为它们是RuntimeException. 所以编译器不会检查它们。编译器会检查非RuntimeException对象,例如Exception,它解释了您所看到的内容。

因为您在main()调用堆栈的底部捕获异常,所以我认为最好通过catch (Exception e)替换来涵盖所有意外情况。

于 2013-12-12T00:40:15.927 回答
1

抛出作为 RuntimeException 子类的异常的方法不必声明它仅在该方法之后抛出该异常。这就是为什么第一个代码运行良好的原因。

但是,当您将异常类型更改为Non-RuntimeException时,您必须使方法抛出异常,否则会出现编译错误。这就是第二个代码出错的原因。

于 2013-12-12T01:10:14.503 回答
0

其他答案涵盖了编译器不满意的原因以及您可以做些什么。但我认为你真正的错误是Exception首先抛出。

投掷Exception几乎总是一个坏主意。原因是如果您的代码 throws Exception,它(或其他人的代码)通常必须捕获​​异常。但是捕获的问题Exception是您的代码还捕获Exception了您的代码可能抛出的任何/所有子类型。这包括可能由代码中的错误等引起的未经检查的异常。

例如:

public class Test {
    private static Integer a;
    private static Integer b;

    public static void main(String[] args) {
        try {
            if (a.equals(b)) {
                throw Exception("they are the same");
            } 
            System.out.println("they are different");
        } catch (Exception ex) {
            System.out.println(ex.message());
        }
    }
}

当你运行它时,你会得到神秘的输出“null”。(读者练习……找出原因。)

将方法声明为throws Exception更糟糕,因为现在调用者被迫要么捕获Exception(错误)或传播它(更糟糕)。被宣布为癌症的方法throws Exception就像癌症。

main将方法声明throws Exception为特殊情况。main 方法(通常)由 JVM 基础架构调用,旨在应对任何异常。它只是将堆栈跟踪打印到标准错误。即便如此,自己处理异常可能更整洁。在“生产级”代码库中,您通常希望在错误日志中记录意外异常。

于 2013-12-12T01:11:10.623 回答