2014-10-06 2 views
1

У меня возникли проблемы с пониманием следующего. У меня есть класс с именем TestClass20, который, когда я скомпилировать и запустить я получаю следующий результат:Throwing NullPointerException в блоке catch

Exception in thread "main" MyException 
     at TestClass20.m1(TestClass20.java:21) 
     at TestClass20.main(TestClass20.java:17) 

//TestClass20.java

class MyException extends IllegalArgumentException{} 
public class TestClass20{ 
    public static void main(String[] args){ 
     TestClass20 tc = new TestClass20(); 
     try{ 
     tc.m1(); 
     } 
     catch (MyException e){ 


     tc.m2(); // THIS IS LINE 11 



     } 
     finally{ 
      tc.m1(); // THIS IS LINE 17 
     } 
    } 
    public void m1() throws MyException{ 
     throw new MyException(); //THIS IS LINE 21 
    } 
    public void m2() throws RuntimeException{ 
     throw new NullPointerException(); 
    } 
} 

Проблема у меня есть, почему линия 11 не бросать любые Исключение нулевого указателя. Строка 11 вызывает метод m2(), который бросает новое исключение NullPointerException, поэтому я ожидаю, что он выкинет NullPointerException. Выход я ожидал должен быть:

Exception in thread "main" java.lang.NullPointerException // Exception that should have been thrown by line 11 

Тогда

Exception in thread "main" MyException // Exception thrown by line 17. 

В итоге: линии 11 должен быть выброшен NullPointerException первый, а затем линия 17 бросков MyException

Если я немного изменить код к такому:

//TestClass21.java

class MyException extends IllegalArgumentException{} 
public class TestClass21{ 
    public static void main(String[] args){ 
     TestClass21 tc = new TestClass21(); 


     tc.m2(); //LINE 7 




    } 
    public void m1() throws MyException{ 
     throw new MyException(); 
    } 
    public void m2() throws RuntimeException{ 
     throw new NullPointerException(); 
    } 
} 

Тогда я получаю следующий результат:

Exception in thread "main" java.lang.NullPointerException 
     at TestClass21.m2(TestClass21.java:17) 
     at TestClass21.main(TestClass21.java:7) 

Так почему же NullPointerException отпечатки в TestClass21.java, но не печатать в TestClass20.java? Невозможно ли распечатать исключение (исключение NullPointerException или любое другое исключение RuntimeException) в блоке catch?

Любое объяснение было бы весьма полезно.

Благодаря

+0

У вас есть 'tc.m1(); 'в окончательном блоке, поэтому MyException выбрано. –

+0

Почему вы ожидали чего-то другого? Выполняется блок 'finally' * всегда *. Было бы даже, если бы исключение вообще не было выброшено в диапазон 'try'. –

ответ

5

Вы tc.m1(); в конце концов блокировать так MyException брошено.

И, наконец, он всегда выполняется, поэтому последнее исключение - это тот, который был брошен наконец. И да NullPointerException также выбрасывается, но в блоке finally он подавляется MyException.

Удалите tc.m1(); из, наконец, блок, и вы увидите ваш NullPointerException

+0

Спасибо Subir.Это, похоже, отвечает на мой вопрос, хотя я не совсем понимаю, почему NullPointerException получает подавление от MyException. –

+0

Простой ответ заключается в том, что это потому, что только одно исключение может выйти из блока try-catch-finally. И по определению это тот, который бросил «наконец». – biziclop

+0

хороший. благодаря –

1

Я думаю, что это, как вы можете достичь того, чего вы хотите.

class MyException extends IllegalArgumentException{} 
public class TestClass20{ 
    public static void main(String[] args){ 
     TestClass20 tc = new TestClass20(); 
     try{ 
     tc.m2(); 
     } 
     catch (NullPointerException e){ 

     e.printStackTrace(); 

     } 
     finally{ 
      tc.m1(); 
     } 
    } 
    public void m1() throws MyException{ 
     throw new MyException(); 
    } 
    public void m2() throws NullPointerException{ 
     throw new NullPointerException(); 
    } 
} 
1

Java 7 введен способ борьбы с ситуациями, как это, вы можете использовать addSuppressed() метод Throwable сигнализировать, что ваши очистки (что вы хотите поместить в блоке, наконец) не закончится нормально ,

try { 
     Exception e1 = null; 
     try { 
      throw new Exception("original"); 
     } catch(Exception ex) { 
      e1 = ex; 
      throw ex; 
     } 
     finally { 
      try { 
       throw new Exception("from finally"); 
      } catch(Exception e2) { 
       if (e1 != null) 
        e1.addSuppressed(e2); 
      } 
     } 
    } catch(Exception ex) { 
     System.out.println(ex.getMessage()); 
     for (Throwable t : ex.getSuppressed()) { 
      System.out.println("Suppressed: "+t.getMessage()); 
     } 
    } 

Созданная в Java 7 конструкция try-with-resources работает аналогичным образом.