有关多次“捕获”的问题

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

为什么不会捕获其他exception(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");} } } 

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

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

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

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

 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!" } 

在创建另一个exception期间可能抛出exception

 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!!" } 

你只能catchtry地方抛出的东西

 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! 

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

afinally块打印。

无论是否抛出exception,始终执行finally块。

编辑:

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

旁注:您通常不应该捕获NullPointerException 。 请参阅Sun网站上的本教程 。

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

如果颠倒catch块的顺序,则将执行Exception块。 (但不建议这样做。您应该按照最具体的顺序将catch块放在最不具体的顺序,就像在示例中一样。)

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

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

因此,您从NullPointerException catch块获取“x”输出,并从finally块输出“a”。

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

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

try / catch的工作方式如下:

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

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

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

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

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