Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about multiple 'catch'

Can anyone tell me why the output of this class is 'xa'?

why the other exception(RuntimeException and Exception ) won't be caught?

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");}
    }
}
like image 817
chun Avatar asked May 07 '10 13:05

chun


2 Answers

Just because an exception is created, doesn't mean it's thrown

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

Just because there's a catch clause, doesn't mean something was caught

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 can be thrown during the creation of another 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!!"
}

You can only catch things thrown from where your try is

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

Practically under "all" circumstances, finally is always executed

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

Abrupt completion of finally trumps abrupt completion of 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!
like image 95
polygenelubricants Avatar answered Oct 23 '22 06:10

polygenelubricants


The only exception thrown is the one right next to the throw statement. The other is created but not thrown. It is not possible to throw two exceptions simultaneously.

Typically when an exception is passed in the constructor of another exception it is to indicate that the that exception is the cause of this one. However, the only exception actually being thrown is the one next to the throw statement.

In this case NullPointerException does not support an Exception in its constructor because it is not caused by other exceptions, it is caused by null references. In other cases it is because exception chaining was not introduced in Java until 1.4, so some legacy exception classes didn't get retro-fitted with new constructors. In that case you can use the initCause(Throwable) method to do what the constructor would have done.

like image 12
Yishai Avatar answered Oct 23 '22 05:10

Yishai