有关多次“捕获”的问题
谁能告诉我为什么这个类的输出是’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!!" }
你只能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!
x
由第一个catch
块打印( NullPointerException
)。
a
由finally
块打印。
无论是否抛出exception,始终执行finally
块。
编辑:
只执行一个catch
块。 在您的情况下,由于NullPointerException
扩展RuntimeException
扩展Exception
,接受这些exception的第一个catch
块将处理exception。
旁注:您通常不应该捕获NullPointerException
。 请参阅Sun网站上的本教程 。
只会执行与抛出的exception类型匹配的第一个catch块。 因此,即使NullPointerException
是RuntimeException
和Exception
,它也已经在这些块之前被捕获。
如果颠倒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的工作方式如下:
- 执行正文代码直到结束,或直到抛出exception为止;
- 如果抛出exception并且存在匹配的catch,则执行匹配的catch子句的代码;
- 始终执行 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。