Java 关于多重';捕捉';

Java 关于多重';捕捉';,java,exception-handling,Java,Exception Handling,有人能告诉我为什么这个类的输出是'xa'吗 为什么其他异常(RuntimeException和exception)不会被捕获 public class Tree { public static void main(String... args) { try { throw new NullPointerException(new Exception().toString()); } catch (Nu

有人能告诉我为什么这个类的输出是'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");}
    }
}

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

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


在这种情况下,NullPointerException不支持其构造函数中的异常,因为它不是由其他异常引起的,而是由null引用引起的。在其他情况下,这是因为Java直到1.4才引入异常链接,所以一些旧的异常类没有重新安装新的构造函数。在这种情况下,您可以使用
initCause(Throwable)
方法来执行构造函数将要执行的操作。

第一个
catch
块打印
x
NullPointerException

a
finally
块打印

无论是否引发异常,始终执行
finally

编辑:

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


另一方面:您通常不应该捕获
NullPointerException
。从Sun网站上可以看到这一点。

引发了一个NullPointerException,它被处理并在控制台中打印为“x”


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

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


如果颠倒catch块的顺序,则将执行
异常
块。(但不建议这样做。您应该始终按照最具体到最不具体的顺序放置捕捉块,如示例所示。)

try/catch的工作方式如下:

  • 执行主体代码直到其结束,或者直到抛出异常
  • 如果抛出异常并且存在匹配的catch,则执行匹配catch子句的代码
  • 无论是否引发异常以及是否捕获异常,始终执行最终代码

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


    因此,您从NullPointerException捕获块获得“x”输出,“a”从finally块输出。

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

    因为您只抛出一个异常。您可以随意创建异常,但除非您抛出它们,否则它们将永远不会被捕获。您永远不会抛出泛型异常,因此它永远不会被捕获

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

    try
    {
        throw new Exception();
        throw new NullPointerException();
    }
    catch (NullPointerException e)
    {
      System.out.printlne("first");
    }
    catch (Exception e)
    {
      System.ot.println("second");
    }
    
    编译器会将您踢出,因为第二次抛出是无法访问的代码。异常就像跳转一样。

    创建异常并不意味着抛出异常 仅仅因为有一个
    catch
    子句,并不意味着有什么东西被捕获了 在创建另一个异常期间可以引发异常 您只能从您的
    try
    所在的位置捕获抛出的东西 实际上,在“所有”情况下,
    最终总是执行
    突然完成
    finally
    胜过突然完成
    try/catch

    你不应该抓住nullpointerException你已经在它周围跳舞了,但是这些例子实际上都没有回答这个问题。这是对这个问题最合适的答案。
    public static void main(String[] args) {
        new Exception();
        System.out.println("Yippee!!");
        // prints "Yippee!!"
    }
    
    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!!"
    }
    
    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
    
    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
    
    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!