Это хорошо, чтобы поймать более общий тип исключения? - PullRequest
5 голосов
/ 21 мая 2009

Если мы собираемся поймать определенные формы IOException, или любой другой вид как на самом деле, и мы только пытаемся поймать пару (и определить окончательные результаты для них) скажем

FileNotFoundException
ZipException

если мы всегда отстаем и покрываем все базы

catch(IOException e){
    e.printStackTrace();
}

, а затем, возможно, пойти еще дальше и поймать Exception e, или это полная трата времени?

Ответы [ 10 ]

9 голосов
/ 21 мая 2009

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

4 голосов
/ 21 мая 2009

Как правило, вы должны перехватывать только те исключения, которые собираетесь обрабатывать явно.

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

3 голосов
/ 21 мая 2009

Если сомневаетесь, всегда поймайте более конкретное исключение!

2 голосов
/ 21 мая 2009

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

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

Но чтобы ответить прямо на ваш вопрос, IOException может быть на соответствующем уровне. Для вас может быть достаточно знать, что какая бы проблема ни была, она связана с IO, и вы можете действовать в соответствии с ней. Трудно сказать без дополнительной информации.

1 голос
/ 22 мая 2009

Я думаю, что это вопрос личных предпочтений. Лично это, кажется, не хороший выбор. Я предпочитаю иметь код, который имеет смысл для меня с try-catch. Это значит быть как можно более конкретным. Я бы сказал:

try{
    //Code Here
}
catch(FileNotFoundException e){
    //Code Here
}
1 голос
/ 21 мая 2009

Неполная отлов любого исключения - не очень хорошая идея. Да, как родительское исключение, он, кажется, обеспечивает уровень «защиты», но это плохо по нескольким причинам:

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

Что еще более важно, вы не ловите исключения, чтобы просто заставить их уйти. Если они это сделали, вы можете просто обернуть все свои методы в (catch (Exception e) {..}) и покончить с этим. Ваш код перехвата исключений должен быть тем местом, где вы решаете, что делать в случае возникновения таких ошибок, например,

catch(FileNotFoundException e)
{
 log.error("where's the file?");return null;
}
catch(ZipException e)
{
 log.error("corrupt");return null;
}

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

1 голос
/ 21 мая 2009

Как хороший консультант, я говорю «все зависит».

В целом в Java у вас есть четкое представление о том, какими могут быть все возможные исключения в конкретном месте кода. Нередко можно увидеть, как кто-то использует

} catch (Exception e){
   // log or stack trace
}

... в более или менее одноразовом коде. В целом, однако, вы не должны ловить исключение, которое вы не знаете, как с этим справиться. (Никогда, никогда , никогда , делайте catch (Exception x) ;, т. Е. Просто выбросьте исключение. Никогда.)

Главное - спросить: «Что я могу с этим сделать?» Зачастую исключение из файла, не являющееся результатом, может быть обработано путем запроса у пользователя, куда ушел его файл. Исключение из архива сложнее обработать. Таким образом, вы можете захотеть иметь отдельное поведение.

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

Еще один совет; не выводите трассировку стека в коде, обращенном к клиенту - код, который может увидеть не программист. Непрограммисты склонны смотреть на полноту трассировки стека и паники. Лучше перевести исключение в сообщение типа «Файл« имя файла »не найден». и, если вам действительно нужна трассировка стека, ose logging отправит ее на выход уровня отладки.

0 голосов
/ 22 мая 2009

Зависит от того, поможет ли более конкретное исключение при устранении неисправностей. Иногда, как и в JMX, хорошо просто перехватить родительское исключение, чтобы избежать длинного списка возможных дочерних исключений. По крайней мере, Java 7 позволит нам иметь более одного исключения на один улов. Это немного очистит код.

0 голосов
/ 22 мая 2009

Я повторю "поймать самое конкретное исключение, которое вы можете".

Я обычно ловлю IOException и отображаю какое-то сообщение «Ошибка чтения файла», затем позволяю пользователю выбрать другой файл или что-то еще подходящее. Если файл действительно плохой, вероятно, пользователь мало что может с этим поделать, но, по крайней мере, вы можете сообщить ему, что файл плохой.

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

Я почти никогда не ловлю "Исключение". Что вы собираетесь с этим делать? Вы практически ничего не можете сделать, чтобы оправиться от «что-то пошло не так, но дальнейшие подробности отсутствуют». В некоторых контекстах, я полагаю, вы могли бы хотя бы отобразить сообщение об ошибке, а не просто умереть, но это все.

0 голосов
/ 21 мая 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...