Вопрос по java, exception, throwable – Лучшие практики для ловли Throwable в Java

12

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

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

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

Любые другие лучшие практики?

ThreadDeath также должен быть переброшен, но он не должен быть переброшен в первую очередь. Tom Hawtin - tackline
Почему комментарий, это просто ответ, который я хотел? ripper234

Ваш Ответ

4   ответа
12

Наверное, самый важный,never swallow a checked exception, Я имею в виду, что не делаю этого:

try {
  ...
} catch (IOException e) {
}

unless that's what you intend, Иногда люди проглатывают проверенные исключения, потому что они не знают, что с ними делать, или не хотят (или не могут) загрязнить свой интерфейс с помощью «throws Exception». статьи.

Если вы не знаете, что с этим делать, сделайте следующее:

try {
  ...
} catch (IOException e) {
  throw new RuntimeException(e);
}

Другой, который приходит на ум, это убедиться, что вы имеете дело с исключениями. Чтение файла должно выглядеть примерно так:

FileInputStream in = null;
try {
  in = new FileInputStream(new File("..."));;
  // do stuff
} catch (IOException e) {
  // deal with it appropriately
} finally {
  if (in != null) try { in.close(); } catch (IOException e) { /* swallow this one */ }
}
Ужас проверенных исключений ... ловить IOException только для того, чтобы обернуть его в непроверенное исключение и НЕ делать с ним вообще ничего? Конечно, это то, что вам нужно делать на Java, если вы на самом деле не знаете, почему вы получаете исключение.
Если вы не можете с этим справиться и не можете перебросить его, хотя бы распечатайте эту трассировку стека! Трассировка стека в журнале очень помогает в диагностике проблемы.
-1 Вопрос в том, чтобы поймать метания и лучшие методы, а не в том, чтобы проглотить проверенные исключения.
Когда Java добавила catch (Throwable)? Или он всегда был там, а я об этом не знал?
+1 для никогда не глотать проверенное исключение - даже в вашем «первом проходе». слишком часто эти вещи упускаются из виду и в конечном итоге передаются в систему контроля версий. если сомневаетесь, хотя бы выведите трассировку стека.
2

возможно, его суперкласса VirtualMachineError)? Я не могу себе представить, что вы можете многое сделать после чего-то такого серьезного.

ЛовитьVirtualMachineError сложно, потому что ваша программа находится в неопределенном состоянии:stackoverflow.com/questions/8728866/…
Если поток, который выделил много объектов, случайно обнаружил ошибку OutOfMemoryError в момент, когда выделенный объект стал сборщиком мусора, ВМ может восстановиться. Если на объекты все еще ссылаются, то да, вы не можете ничего сделать, кроме как выйти или освободить некоторые объекты.
1

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

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

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

Потому что InterruptedException просто указывает, что кто-то вызвал interrupt () в потоке. Для этого может быть несколько причин, а не просто прекращение текущего действия. И если вы хотите использовать interrupt () для завершения работы диспетчера, вы, безусловно, не хотите его выбрасывать; просто вернитесь из run () - если, конечно, ваш диспетчер - не единственное, что делает поток, но даже там вы почти наверняка не захотите бросать вслепую.
Почему проверка внешнего состояния лучше, чем использование InterruptedException в качестве механизма сигнализации? ripper234
2

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

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

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