关于多个“捕获”的问题

时间:2010-05-07 13:36:45

标签: java exception-handling

有谁能告诉我为什么这个类的输出是'xa'?

为什么不会捕获其他异常(RuntimeException和Exception)?

public class Tree {
    public static void main(String... args) {
        try
        {
            throw new NullPointerException(new Exception().toString());
        }
        catch (NullPointerException e)
        {
            System.out.print("x");
        }
        catch (RuntimeException e)
        {
            System.out.print("y");
        }
        catch (Exception e)
        {
            System.out.print("z");   
        }        
        finally{System.out.println("a");}
    }
}

9 个答案:

答案 0 :(得分:16)

仅仅因为创建了异常,并不意味着它被抛出

public static void main(String[] args) {
    new Exception();
    System.out.println("Yippee!!");
    // prints "Yippee!!"
}

仅仅因为有一个catch条款,并不意味着被抓住了

public static void main(String[] args) throws Exception {
    try {
        System.out.println("No math for me!");
    } catch (ArithmeticException e) {
        System.out.println("Math was wronged!");
    } // prints "No math for me!"
}

在创建另一个异常

期间可能抛出异常
public static void main(String[] args) {
    try {
        throw new NullPointerException(args[-1]);
    } catch (NullPointerException e) {
        System.out.println("Ooops!");
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("Ooh lala!!");           
    } // prints "Ooh lala!!"
}

catch

的地方只能发送try件事
public static void main(String[] args) throws Exception {
    try {
        args[-1] = null;
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("Gotcha!");
        args[1/0] = null;
    } catch (ArithmeticException e) {           
        System.out.println("You missed me!");
    } // prints "Gotcha!"
} // Exception in thread "main" java.lang.ArithmeticException: / by zero

实际上在“所有”情况下,finally总是被执行

public static void main(String[] args) {
    try {
        throw new Exception();
    } catch (Exception e) {
        System.out.println("Oops!");
        args[-1] = null;
    } finally {
        System.out.println("Yay!");
    } // prints "Oops!", "Yay!",
} // Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1

突然完成finally突然完成try/catch

static String greetings() {
    try {
        return "No mood!";
    } finally {
        return "Hey buddy!";
    }
}   
public static void main(String[] args) throws Exception {
    System.out.println(greetings()); // prints "Hey buddy!"
    try {
        args[-1] = null;
    } catch (ArrayIndexOutOfBoundsException e) {
        throw new Exception("Catch me if you can!");
    } finally {
        throw new Exception("Yoink!");
    }
} // Exception in thread "main" java.lang.Exception: Yoink!

答案 1 :(得分:12)

抛出的唯一异常是throw语句旁边的异常。另一个是创建但不抛出。不可能同时抛出两个例外。

通常,当在另一个异常的构造函数中传递异常时,它指示该异常是该异常的原因。但是,实际抛出的唯一异常是throw语句旁边的异常。

在这种情况下,NullPointerException在其构造函数中不支持Exception,因为它不是由其他异常引起的,而是由null引用引起的。在其他情况下,这是因为在1.4之前没有在Java中引入异常链接,因此一些遗留异常类没有得到新构造函数的改编。在这种情况下,您可以使用initCause(Throwable)方法来执行构造函数的操作。

答案 2 :(得分:7)

x由第一个catch块(NullPointerException)打印。

a块打印finally

无论是否抛出异常,始终会执行finally块。

编辑:

只会执行一个catch块。在您的情况下,由于NullPointerException扩展RuntimeException扩展Exception,因此接受这些异常的第一个catch块将处理该异常。

旁注:您通常不应该抓住NullPointerException。请参阅Sun网站上的tutorial

答案 3 :(得分:6)

只会执行与抛出的异常类型匹配的第一个catch块。因此即使NullPointerExceptionRuntimeExceptionException,它也已经在这些块之前被捕获。

如果颠倒catch块的顺序,则Exception块将执行。 (但不建议这样做。你应该总是把你的catch块按照最具体到最不具体的顺序排列,就像你在例子中那样。)

答案 4 :(得分:3)

在这里,您在try块中抛出NullPointerException,因此它将被捕获在适用的第一个catch块中。一旦它被捕获,就会被抓住。

答案 5 :(得分:2)

Java使用与引发Exception匹配的第一个 catch块处理异常。因此抛出的异常是NullPointerException,它被第一个catch块捕获,其余的被忽略。始终执行finally块(除非您异常终止,例如System.exit)。

所以你从NullPointerException catch块得到“x”输出,并从finally块输出“a”。

答案 6 :(得分:0)

抛出NullPointerException并在控制台中处理并打印“x”。

然后执行finally语句并将“a”打印到控制台,因此你得到了“xa”。

答案 7 :(得分:0)

try / catch的工作方式如下:

  1. 执行正文代码直到结束,或直到抛出异常为止;
  2. 如果抛出异常并且存在匹配的catch,则执行匹配的catch子句的代码;
  3. 始终执行最终代码,无论是否抛出异常,以及是否被捕获

答案 8 :(得分:0)

因为你只抛出一个例外。您可以创建所有您喜欢的例外,但除非您抛出它们,否则它们永远不会被捕获。你永远不会抛出通用的异常,所以它永远不会被捕获。

顺便说一下,没有办法同时抛出两个例外。如果你写:

try
{
    throw new Exception();
    throw new NullPointerException();
}
catch (NullPointerException e)
{
  System.out.printlne("first");
}
catch (Exception e)
{
  System.ot.println("second");
}

编译器会将你踢出去,因为第二次抛出是无法访问的代码。例外情况就像是GOTO。