2009-05-21 2 views
5

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

FileNotFoundException
ZipException

мы должны всегда тянуться его и охватить все основания с

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

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

ответ

9

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

2

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

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

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

+0

Re: непоследовательное состояние, я считаю, что, наконец, блоки всегда выполняются на Java, поскольку исключение вылетает из стека, независимо от того, было ли исключено исключение. Поэтому, даже если вы стараетесь не улавливать «фатальные» исключения, чтобы избежать выполнения, когда вы находитесь в противоречивом состоянии, у вас нет возможности остановить выполнение ваших блоков finally.Таким образом, ИМО это спорный вопрос в JRE, если вы не избегаете использования блоков finally, которые кажутся ужасными, когда приходится сдаваться. .NET CLR отличается - у вас есть возможность прервать BEFORE, наконец, будут выполняться блоки, если есть необработанное исключение. –

1

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

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

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

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

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

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

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

4

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

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

0

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

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

1

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

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

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

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

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

+0

Не быть уколотием; но когда я вижу это, я думаю, что это вызовет NPE в другом месте. – sal

3

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

0

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

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

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

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

0

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

1

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

try{ 
    //Code Here 
} 
catch(FileNotFoundException e){ 
    //Code Here 
}