Вопрос о нескольких 'ловит'

Кто-либо может сказать мне, почему вывод этого класса является 'xa'?

почему другое исключение (RuntimeException и Исключение) не будет поймано?

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
задан chun 7 May 2010 в 13:47
поделиться

9 ответов

Единственное исключение, которое выбрасывается, это то, которое находится прямо рядом с оператором throw. Другое исключение создается, но не выбрасывается. Невозможно бросить два исключения одновременно.

Обычно, когда исключение передается в конструктор другого исключения, это указывает на то, что то исключение является причиной этого. Однако на самом деле выбрасывается только то исключение, которое находится рядом с оператором throw.

В этом случае NullPointerException не поддерживает исключение в своем конструкторе, потому что оно не вызвано другими исключениями, оно вызвано нулевыми ссылками. В других случаях это связано с тем, что цепочка исключений не была введена в Java до версии 1.4, поэтому некоторые устаревшие классы исключений не были оснащены новыми конструкторами. В этом случае вы можете использовать метод initCause(Throwable), чтобы сделать то, что должен был сделать конструктор.

12
ответ дан 4 December 2019 в 06:06
поделиться

То, что создается исключение, не означает, что оно выбрано

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

Вы можете только поймать вещи, выброшенные из того места, где ваша попытка

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!
16
ответ дан 4 December 2019 в 06:06
поделиться

x печатается первым блоком catch (исключение NullPointerException ).

a печатается блоком finally .

Блок finally выполняется всегда, независимо от того, было сгенерировано исключение или нет.

РЕДАКТИРОВАТЬ:

Будет выполнен только один блок catch . В вашем случае, поскольку NullPointerException extends RuntimeException extends Exception , первый блок catch , который принимает эти исключения, будет обрабатывать исключение.

Замечание: обычно вы не должны обнаруживать NullPointerException . См. Это учебное пособие на веб-сайте Sun.

7
ответ дан 4 December 2019 в 06:06
поделиться

Здесь вы бросаете исключение NullPointerException в блоке try, и поэтому оно будет перехвачено в первом применяемом блоке catch. Как только он пойман, он пойман.

3
ответ дан 4 December 2019 в 06:06
поделиться

Java обрабатывает исключение с помощью первого блока catch, который соответствует выброшенному исключению. Так как брошенное исключение - это NullPointerException, оно перехватывается первым блоком catch, а остальные игнорируются. Блок finally всегда выполняется (если только вы не завершаете работу аномально, например, System.exit).

Таким образом, вы получаете вывод "x" из блока отлова NullPointerException, а "a" выводится из блока finally.

2
ответ дан 4 December 2019 в 06:06
поделиться

Принцип работы try/catch следующий:

  1. Код тела выполняется до конца, или пока не будет выброшено исключение;
  2. Если выброшено исключение и есть соответствующий catch, выполняется код соответствующего пункта catch;
  3. Код finally выполняется всегда, независимо от того, было ли выброшено исключение, и было ли оно поймано
0
ответ дан 4 December 2019 в 06:06
поделиться

Потому что вы бросаете только одно исключение. Вы можете создавать исключения сколько угодно, но пока вы их не бросите, они никогда не будут пойманы. Вы никогда не бросаете общее исключение Exception, поэтому оно никогда не может быть поймано.

И кстати, не существует способа бросить два исключения одновременно. Если вы напишете:

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

Компилятор просто выкинет вас, потому что второй бросок - это недостижимый код. Исключение - это как GOTO.

0
ответ дан 4 December 2019 в 06:06
поделиться

Возникла исключительная ситуация NullPointerException, которая была обработана и напечатана в консоли.

Затем выполняется оператор finally и выводится «a» на консоль, и, следовательно, вы получаете «xa».

0
ответ дан 4 December 2019 в 06:06
поделиться

Будет выполнен только первый блок catch, соответствующий типу брошенного исключения. Поэтому, даже если NullPointerException является RuntimeException и Exception, оно уже было поймано до этих блоков.

Если вы измените порядок блоков catch, то будет выполнен блок Exception. (Однако это не рекомендуется. Всегда следует располагать блоки catch в порядке от наиболее специфичного к наименее специфичному, как в примере)

.
6
ответ дан 4 December 2019 в 06:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: