2009-09-03 3 views
32

Почему некоторые исключения из Java не пойманы catch (Exception ex)? Это код полностью не работает с необработанным исключением. (Java Version 1.4).Исключение Java исключено

public static void main(String[] args) { 
    try { 
     //Code ... 
    } catch (Exception ex) { 
     System.err.println("Caught Exception"); 
     ex.printStackTrace(); 
     exitCode = app.FAILURE_EXIT_CODE; 
    } 
    finally { 
     app.shutdown(); 
    } 
    System.exit(exitCode); 
} 

Я получаю Exception in thread "main" java.lang.NoSuchMethodError

Но это работает

public static void main(String[] args) { 
    int exitCode = app.SUCCESS_EXIT_CODE; 
    try { 
     //Code ... 
    } catch (java.lang.NoSuchMethodError mex){ 
     System.err.println("Caught NoSuchMethodError"); 
     mex.printStackTrace(); 
     exitCode = app.FAILURE_EXIT_CODE; 
    } catch (Exception ex) { 
     System.err.println("Caught Exception"); 
     ex.printStackTrace(); 
     exitCode = app.FAILURE_EXIT_CODE; 
    } 
    finally { 
     app.shutdown(); 
    } 
    System.exit(exitCode); 
} 

Я получаю Caught NoSuchMethodError java.lang.NoSuchMethodError:

Я думал, что перехват исключений будет перехватывать все исключения? Как я могу уловить все исключения в java?

ответ

99

Поскольку некоторые исключения не являются результатом Exception - например, Throwable и Error.

В принципе иерархии типов:

 Object 
     | 
     Throwable 
    /  \ 
Exception  Error 

Только Throwables и производные классы могут быть выброшены, так что если вы ловите Throwable, что на самом деле будет ловить все.

Любое исключение, вытекающие из Exception (или Exception сам) другие, чем те, которые получены из RuntimeException подсчета, как проверяемые исключения - они те, которые вы должны объявить, что вы будете бросать, или поймать, если вы звоните что-то что бросает их.

Все сказали, иерархия исключений Java является немного беспорядок ...

+6

+1: хорошая диаграмма! – akf

+1

Ошибки на самом деле не являются исключениями, поэтому почему они не происходят из Исключения. – Powerlord

+2

@R. Bemrose - они соответствуют спецификации языка Java: «Каждое исключение представлено экземпляром класса Throwable или одним из его подклассов», а «Непроверенными классами исключений являются класс RuntimeException и его подклассы, а класс Error и его подклассы «. –

3

Вы можете поймать Throwable. Ошибка и исключение: Throwable.

см Throwable JavaDoc:

Throwable класс является суперклассом всех ошибок и исключений на языке Java.

4

Исключение - только один вид Throwable; NoSuchMethodError не исключение, а ошибка, которая является другим типом Throwable.

0

Как и другие сообщения указывают, catch (исключение e) будет работать только для исключений, которые происходят от Exception. Однако, если вы посмотрите на иерархию дерева, вы заметите, что исключение, если Throwable. Throwable также является базовым классом для Error. Таким образом, в случае NoSuchMethodError это ошибка, а не исключение. Обратите внимание на соглашение об именах * Ошибка против * Исключение (например, в IOException).

1

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

+0

В конце концов, все равно выполнится ошибка? –

+0

Да. Но у вас могут быть другие проблемы. например что произойдет, если/когда вы поймаете OutOfMemoryError? –

5

Error s не Exception s.

Класс Exception и его подклассы являются формой Throwable, что указывает условия, которые разумное применение могли бы хотеть поймать.

- JavaDoc for java.lang.Exception

об ошибке подкласс Throwable , что указывает на серьезные проблемы, с которыми разумное приложение не должно попытаться поймать.

- JavaDoc for java.lang.Error

Есть некоторые ошибки, которые вы можете поймать, такие как ThreadDeath. ThreadDeath классифицируются как ошибка, как описано ниже

Класса ThreadDeath специально подкласс Error, а не Exception, несмотря на то, что это «нормальное явления», потому что многие приложения поймать все вхождения Исключение и , то отмените исключение.

- JavaDoc for ThreadDeath

Однако, поскольку метод остановки потока() теперь не рекомендуется, вы не должны использовать его, и, таким образом, вы никогда не должны видеть ThreadDeath.

+0

Спецификация языка Java не согласуется с вами: «Неконтролируемые классы исключений - это класс RuntimeException и его подклассы, а также класс Error и его подклассы». –

+0

Я особенно ценю совет о том, чтобы не ловить Ошибки. Рассмотрим «OutOfMemoryErrors» - приложение может быть оставлено в плохом состоянии после его выброса. Было бы нецелесообразно ловить и отбросить этот «Ошибка». – akf

+0

В принципе, JLS всегда ссылается на «вещи, которые могут быть выброшены и пойманы» в качестве исключений. Вы ничего там не цитировали, говорит, что ошибка не является исключением. –

Смежные вопросы