В каких ситуациях следует улавливать java.lang.Error
в приложении?
Когда нужно поймать java.lang.Error?
Ответ 1
Как правило, никогда. Однако иногда вам нужно поймать определенные ошибки.
Если вы пишете фрейм-иш-код (загружаете сторонние классы), может быть разумным уловить LinkageErrors (нет определения класса def, неудовлетворенной ссылки, несовместимого изменения класса). Я также видел какой-то глупый сторонний код, бросающий поддоны Ошибок, поэтому вам также придется обрабатывать их.
Кстати, я не уверен, что восстановление OutOfMemory невозможно.
Ответ 2
Никогда. Вы никогда не можете быть уверены, что приложение сможет выполнить следующую строку кода. Если вы получаете OutOfMemoryError
, у вас нет гарантии, что вы сможете сделать что-либо надежно. Catch RuntimeException и проверено Исключения, но никогда Ошибки.
Ответ 3
Как правило, вы всегда должны ловить java.lang.Error
и записывать его в журнал или отображать его пользователю. Я работаю в поддержку и ежедневно вижу, что программисты не могут сказать, что произошло в программе.
Если у вас есть поток демона, вы должны запретить его завершение. В других случаях ваше приложение будет работать правильно.
Вы должны ловить java.lang.Error
только на самом высоком уровне.
Если вы посмотрите на список ошибок, вы увидите, что большинство из них можно обрабатывать. Например, ZipError
происходит при чтении поврежденных zip файлов.
Наиболее распространенными ошибками являются OutOfMemoryError
и NoClassDefFoundError
, которые в большинстве случаев являются проблемами времени выполнения.
Например:
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
может создать OutOfMemoryError
, но это проблема времени выполнения и никаких причин для завершения вашей программы.
NoClassDefFoundError
встречаются в основном, если библиотека отсутствует или вы работаете с другой версией Java. Если это необязательная часть вашей программы, вы не должны прерывать свою программу.
Я могу привести еще много примеров того, почему хорошая идея поймать Throwable
на верхнем уровне и создать полезное сообщение об ошибке.
Ответ 4
В многопоточной среде вы чаще всего хотите ее поймать! Когда вы поймаете его, запишите его и прекратите все приложение! Если вы этого не сделаете, какой-то поток, который может сыграть важную роль, будет мертв, а остальная часть приложения будет думать, что все нормально. Из-за этого может возникнуть много нежелательных ситуаций. Одна из самых маленьких проблем заключается в том, что вы не сможете легко найти корень проблемы, если другие потоки начинают бросать некоторые исключения из-за того, что один поток не работает.
Например, обычно цикл должен быть:
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
Даже в некоторых случаях вы хотели бы обрабатывать разные Ошибки по-разному, например, в OutOfMemoryError вы могли бы закрыть приложение регулярно (даже, возможно, освободить некоторую память и продолжить), на некоторых других, вас не так много возможно.
Ответ 5
Очень редко.
Я бы сказал только на верхнем уровне потока, чтобы ATTEMPT выдавал сообщение с причиной смерти потока.
Если вы находитесь в среде, которая делает это для вас, оставьте ее в рамках.
Ответ 6
Почти никогда. Ошибки предназначены для проблем, которые приложения вообще ничего не могут сделать. Единственным исключением может быть обработка представления ошибки, но даже это может не пойти так, как планировалось, в зависимости от ошибки.
Ответ 7
Error
обычно не должен быть пойман, так как он указывает на ненормальное условие, которое никогда не должно происходить.
Из спецификации API Java для Error
класс:
An
Error
является подклассомThrowable
что указывает на серьезные проблемы, которые разумное приложение не должно пытаться ловить. Большинство таких ошибок ненормальные условия. [...]Метод не требуется объявлять в его броски определяют любые подклассы Ошибка, которая может быть выполнение метода, но не поймали, поскольку эти ошибки ненормальные условия, которые никогда не должны происходят.
Как указано в спецификации, Error
вызывается только в обстоятельствах, которые
Скорее всего, когда происходит Error
, приложение может сделать очень мало, и в некоторых случаях сама виртуальная машина Java может находиться в неустойчивом состоянии (например, VirtualMachineError
)
Хотя Error
является подклассом Throwable
, что означает, что он может быть захвачен предложением try-catch
, но, вероятно, это действительно не требуется, так как приложение будет находиться в ненормальном состоянии, когда Error
выбрасывается JVM.
В разделе также содержится небольшой раздел по этой теме. 11.5 Иерархия исключений Спецификация языка Java, 2-е издание.
Ответ 8
Если вы достаточно сумасшедший, чтобы создавать новую инфраструктуру unit test, вашему тестовому бегунщику, вероятно, придется поймать java.lang.AssertionError, брошенную в любых тестовых случаях.
В противном случае см. другие ответы.
Ответ 9
И есть еще несколько случаев, когда, если вы поймаете ошибку, вам нужно сбросить ее. Например, ThreadDeath никогда не должен быть пойман, это может вызвать серьезную проблему - вы поймаете его в замкнутой среде (например, сервере приложений):
Приложение должно захватывать экземпляры этого класса, только если оно должно очистить после его прерывания асинхронно. Если ThreadDeath пойман методом, важно, чтобы он был сброшен так, чтобы поток фактически замирал.
Ответ 10
Очень, очень редко.
Я сделал это только для одного очень специфического известного случая. Например, java.lang.UnsatisfiedLinkError может быть запущен, если две независимые от класса класс ClassLoader загружают одну и ту же DLL. (Я согласен с тем, что я должен переместить JAR в общий загрузчик классов)
Но наиболее распространенным случаем является то, что вам нужно было вести журнал, чтобы узнать, что произошло, когда пользователь пришел, чтобы жаловаться. Вы хотите, чтобы сообщение или всплывающее окно пользователю, а затем молчали.
Даже программист на C/С++, они вызывают ошибку и сообщают, что люди не понимают, прежде чем они выйдут (например, сбой памяти).
Ответ 11
В приложении Android я нахожу java.lang.VerifyError. Библиотека, которую я использую, не будет работать на устройствах со старой версией ОС, а код библиотеки будет вызывать такую ошибку. Я мог бы, конечно, избежать ошибки, проверив версию ОС во время выполнения, но:
- Самый старый поддерживаемый SDK может измениться в будущем для конкретной библиотеки
- Блок ошибок try-catch является частью более крупного механизма возврата. Некоторые конкретные устройства, хотя они должны поддерживать библиотеку, бросают исключения. Я уловил VerifyError и все исключения, чтобы использовать решение отладки.
Ответ 12
довольно удобно поймать java.lang.AssertionError в тестовой среде...
Ответ 13
В идеале мы не должны обрабатывать/улавливать ошибки. Но могут быть случаи, когда нам нужно делать, исходя из требований фреймворка или приложения. Скажем, у меня есть демон XML Parser, который реализует DOM Parser, который потребляет больше памяти. Если есть требование, такое как поток Parser, не следует умирать, когда он получает OutOfMemoryError, вместо этого он должен обрабатывать его и отправлять сообщение/почту администратору приложения/рамки.
Ответ 14
В идеале мы никогда не должны ломать Ошибка в нашем приложении Java, поскольку это ненормальное условие. Приложение будет находиться в ненормальном состоянии и может привести к ловкости или давлению некоторых серьезных неправильных результатов.
Ответ 15
Возможно, уместно уловить ошибку в модульных тестах, которые проверяют утверждение. Если кто-то отключает утверждения или иным образом удаляет утверждение, которое вы хотели бы знать
Ответ 16
Ошибка, когда JVM работает не так, как ожидалось, или находится на грани. Если вы поймаете ошибку, нет гарантии, что блок catch будет работать, и тем более, что он будет работать до конца.
Он также будет зависеть от текущего компьютера, текущего состояния памяти, поэтому нет возможности протестировать, попробовать и сделать все возможное. У вас будет только хороший результат.
Вы также понизите читаемость вашего кода.