Веские причины избегать использования операторов try-catch - PullRequest
6 голосов
/ 26 марта 2011

Пример # 1:

<code>try { fileChooser.setSelectedFile(new File(filename)); }
catch (NullPointerException e) { /* do nothing */ }

Пример № 2:

<code>if (filename != null)
    fileChooser.setSelectedFile(new File(filename));

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


Редактировать: Похоже, консенсус заключается в том, что № 1 нет-нет. Самая популярная причина: накладные расходы

Также у @ Raph Levien было хорошее понимание:

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

Также См. Ссылку для большей глубины.

Ответы [ 7 ]

8 голосов
/ 26 марта 2011

Определенно # 2 - лучший выбор. Обработка исключений не должна использоваться в качестве конструкции в потоке управления вашей программы. Исключения следует использовать для обработки ситуаций, которые не находятся под контролем программиста. В этом примере вы можете проверить, имеет ли fileChooser значение NULL, так что он находится под вашим контролем.

5 голосов
/ 26 марта 2011
  • Не используйте исключение для управления логическим потоком.
  • Никогда не глотай исключение. # 1 нарушает его - вы никогда не узнаете, если NPE от fileChooser==null или fileName==null.
5 голосов
/ 26 марта 2011

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

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

Вот короткая реклама этого ответа:

Исключением являются в основном нелокальные операторы goto со всеми последствиями последнего. Использование исключений для управления потоком нарушает принцип наименьшего удивления, затрудняя чтение программ (помните, что программы сначала пишутся для программистов).

4 голосов
/ 26 марта 2011

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

3 голосов
/ 26 марта 2011

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

2 голосов
/ 02 апреля 2011

Ваши два примера не являются семантически эквивалентными в следующих случаях:

  • fileChooser равно null
  • setSelectedFile бросает NullPointerException (предоставлено, это можетс этим конкретным методом это не произойдет, но в общем случае для установщика вполне возможно сохранить материал в каком-то другом объекте, который сгенерирует, если ссылка на этот другой объект не была инициализирована)
  • new File() бросаетNullPointerException по причинам, отличным от filename, являющимся null

Возможно, /* do nothing */ предназначался только для случая, когда filename равен нулю, но теперь скрывает и другие случаи,в то время как хорошая обработка исключений позволила бы этим исключениям пузыриться в стеке вызовов, предупреждая вас о наличии и причине ошибки, которую в противном случае вам было бы трудно отследить.производительность, потому что потраченное впустую время программиста намного дороже, чем потраченное время процессора.

2 голосов
/ 29 марта 2011

Я бы выбрал вариант № 3 - если в качестве аргумента функции передано filename, поместите в комментарии примечание, что нулевое имя файла не допускается.Затем просто работайте с предположением, что имя файла никогда не равно нулю:

fileChooser.setSelectedFile(new File(filename));

Если какой-то идиот (или вы, <3) проигнорирует ваш комментарий и «действительно» пропустит ноль, он получит исключение NullPointerExceptionи должен решить проблему. </p>

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

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

(rant: Конечно, я должен декомпилировать упомянутый сторонний код и определить, что сам, учитывая, что документациялибо отсутствует, либо не принимает к сведению, что возможно возвращает ноль)

...