Когда ловить java.ленг.Ошибка?



в каких ситуациях нужно поймать java.lang.Error по заявлению?

598   16  

16 ответов:

вообще, никогда. Однако иногда вам нужно поймать определенные ошибки.

Если вы пишете код framework-ish (загрузка сторонних классов), было бы разумно поймать LinkageErrors (не найден класс def, неудовлетворенная ссылка, несовместимое изменение класса). Я также видел некоторые глупые сторонние коды, бросающие подкассы ошибок,поэтому вам придется справиться с ними.

кстати, я не уверен, что это не возможно, чтобы оправиться от OutOfMemory.

никогда. Вы никогда не можете быть уверены, что приложение способно выполнить следующую строку кода. Если вы получаете OutOfMemoryError, вы нет гарантии, что вы сможете сделать что-нибудь надежно. Поймать RuntimeException и проверенные исключения, но не ошибки.

http://pmd.sourceforge.net/rules/strictexception.html

как правило, вы всегда должны поймать java.lang.Error и записать его в журнал или отображать его пользователю. Я работаю в Службе поддержки и ежедневно вижу, что программисты не могут сказать, что произошло в программе.

если у вас есть поток демона, то вы должны предотвратить его прекращения. В других случаях ваше приложение будет работать правильно.

вы должны поймать только java.lang.Error на самом высоком уровне.

если вы посмотрите на список ошибок, вы увидите, что большинство из них может быть обработан. Например,ZipError происходит при чтении поврежденных zip-файлов.

наиболее распространенными ошибками являются OutOfMemoryError и NoClassDefFoundError, которые в большинстве случаев являются проблемами времени выполнения.

например:

int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];

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

NoClassDefFoundError возникают в основном, если библиотека отсутствует или если вы работаете с другой версией Java. Если это необязательная часть программы, то вы не должны завершите свою программу.

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

в многопоточной среде, вы чаще всего хотите, чтобы поймать его! Когда вы поймаете его, войдите в него и завершите все приложение! Если вы этого не сделаете, какой-то поток, который может выполнять какую-то важную часть, будет мертв, а остальная часть приложения будет думать, что все нормально. Из этого может произойти много нежелательных ситуаций. Одна из самых маленьких проблем заключается в том, что вы не сможете легко найти корень проблемы, если другие потоки начнут выбрасывать некоторые исключения из-за того, что один поток не рабочий.

например, обычно цикл должен быть:

try {
   while (shouldRun()) {
       doSomething();
   }
}
catch (Throwable t) {
   log(t);
   stop();
   System.exit(1);
}

даже в некоторых случаях вы хотели бы обрабатывать разные ошибки по-разному, например, на OutOfMemoryError вы могли бы регулярно закрывать приложение (даже, возможно, освободить некоторую память и продолжить), на некоторых других, вы не можете много сделать.

очень редко.

Я бы сказал только на верхнем уровне потока, чтобы попытаться выдать сообщение с причиной смерти Потока.

Если вы находитесь в рамках, которые делают такие вещи для вас, оставьте его в рамках.

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

An Error Как правило, не должны быть пойманы, а это указывает на ненормальное состояние, которое никогда не должно возникать.

из спецификации Java API для Error класс:

An Error является наследником Throwable это указывает на серьезные проблемы, что разумное применение не должно пытаться ловить. Большинство таких ошибок аномальные условия. [...]

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

как указано в спецификации,Error бросается только в обстоятельствах, которые являются Скорее всего, когда Error происходит, есть очень мало приложение может сделать, и в некоторых обстоятельствах, сама виртуальная машина Java может быть в нестабильном состоянии состояние (например,VirtualMachineError)

хотя Error является наследником Throwable что означает, что он может быть пойман try-catch предложение, но это, вероятно, на самом деле не нужно, так как приложение будет находиться в ненормальном состоянии, когда Error бросается JVM.

есть также небольшой раздел по этой теме В разделе 11.5 Иерархия Исключений на спецификация языка Java, 2-е издание.

Если вы достаточно сумасшедшие, чтобы создавать новую платформу модульного тестирования, ваш тестовый бегун, вероятно, должен будет поймать java.ленг.AssertionError выбрасывается любыми тестовыми случаями.

в противном случае см. другие ответы.

и есть еще несколько случаев, когда если вы поймаете ошибку, вы придется переосмыслить его. Например ThreadDeath никогда не должны быть пойманы, это может вызвать большую проблему, вы поймаете его в замкнутой среде (например. сервер приложений) :

приложение должно перехватывать экземпляры этого класса только в том случае, если оно должно очистить после завершения асинхронно. Если ThreadDeath пойман методом, Это важно чтобы он был перестроен так, чтобы нить действительно умирала.

очень, очень редко.

Я сделал это только для одного очень конкретные известные случаи. Например, java.ленг.UnsatisfiedLinkError можно бросить, если два загрузчика независимости загрузить ту же DLL. (Я согласен, что я должен переместить банку в общий загрузчик классов)

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

даже программист на C / C++, они выскакивают ошибку и говорят что-то, что люди не понимают до его выхода (например, сбой памяти).

в приложении для Android я ловлю java.ленг.VerifyError. Библиотека, которую я использую, не будет работать на устройствах со старой версией ОС, и код библиотеки выдаст такую ошибку. Я мог бы, конечно, избежать ошибки, проверив версию ОС во время выполнения, но:

  • самый старый поддерживаемый SDK может измениться в будущем для конкретной библиотеки
  • блок ошибок try-catch является частью большего механизма отката. Некоторые конкретные устройства, хотя они должны поддерживать библиотеку, выбрасывают исключения. Я ловлю VerifyError и все исключения для использования Резервного решения.

Это довольно удобно, чтобы поймать java.ленг.AssertionError в тестовой среде...

В идеале мы не должны обрабатывать/ловить ошибки. Но могут быть случаи, когда нам нужно это сделать, исходя из требований фреймворка или приложения. Скажем, у меня есть демон синтаксического анализа XML, который реализует DOM Parser который потребляет больше памяти. Если есть требование, как парсер поток не должен быть умер, когда он получает OutOfMemoryError, вместо этого он должен обработать его и отправить сообщение/письмо администратору приложения/фреймворка.

в идеале мы никогда не должны ловить ошибку в нашем приложении Java, поскольку это ненормальное состояние. Приложение будет находиться в ненормальном состоянии и может привести к carshing или давая какой-то серьезно неправильный результат.

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

есть ошибка, когда JVM больше не работает, как ожидалось, или находится на грани. Если вы поймать ошибку, нет никакой гарантии, что блок catch будет работать, и даже меньше, что он будет работать до конца.

Это также будет зависеть от работающего компьютера, текущего состояния памяти, поэтому нет никакого способа проверить, попробовать и сделать все возможное. Вам останется только результат опасное.

вы также понизите читаемость вашего кода.

Comments

    Ничего не найдено.