Дело против проверенных исключений

Используйте команду expect stty следующим образом:

# grab the password
stty -echo
send_user -- "Password for $user@$host: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)

#... later
send -- "$pass\r"

Обратите внимание, что для вызова stty -echo перед важно вызвать send_user - я не уверен именно поэтому: я думаю, что это вопрос времени.

Ожидайте, что программисты должны прочитать книгу: «Изучение ожиданий дон Либес»

423
задан Boann 27 November 2013 в 02:11
поделиться

21 ответ

Хорошим доказательством того, что Checked Exception не нужны, являются:

  1. Много фреймворка, который делает некоторую работу для Java. Как Spring, который оборачивает исключение JDBC в непроверенные исключения, выбрасывая сообщения в журнал
  2. Множество языков, которые пришли после java, даже сверху на платформе java - они не используют их
  3. Проверенные исключения, это добрый прогноз о том, как клиент будет использовать код, который выдает исключение. Но разработчик, который пишет этот код, никогда не узнает о системе и бизнесе, в котором работает клиент кода. Например, методы Interfcace, которые вынуждают генерировать проверенное исключение. В системе существует 100 реализаций, 50 или даже 90 реализаций не выдают это исключение, но клиент все равно должен перехватить это исключение, если он ссылается на этот интерфейс. Эти 50 или 90 реализаций, как правило, обрабатывают эти исключения внутри себя, помещая исключения в журнал (и это хорошее поведение для них). Что нам с этим делать? Мне бы лучше иметь некоторую базовую логику, которая бы выполняла всю эту работу - отправлять сообщения в журнал. И если я, как клиент кода, почувствую, что мне нужно обработать исключение - я сделаю это. Я могу забыть об этом, верно, но если я использую TDD, все мои шаги покрыты, и я знаю, чего хочу.
  4. Другой пример, когда я работаю с I / O в Java, это заставляет меня проверять все исключения, если файл не существует? что мне с этим делать? Если он не существует, система не перейдет к следующему шагу. Клиент этого метода не получит ожидаемое содержимое из этого файла - он может обработать исключение времени выполнения, в противном случае я должен сначала проверить Checked Exception, поместить сообщение в журнал, а затем выбросить исключение из метода. Нет ... нет - я бы лучше сделал это автоматически с RuntimeEception, который делает это / загорается автоматически. Нет никакого смысла обрабатывать это вручную - я был бы рад, что увидел сообщение об ошибке в журнале (AOP может помочь с этим .. что-то, что исправляет Java). Если, в конце концов, я угадаю, что система должна показывать всплывающее сообщение конечному пользователю - я покажу это, не проблема.

Я был бы счастлив, если бы java предоставил мне выбор , что использовать при работе с основными библиотеками, такими как I / O. Like предоставляет две копии одних и тех же классов - один обернут в RuntimeEception. Тогда мы можем сравнить, что люди будут использовать . На данный момент, тем не менее, многим лучше пойти на какую-то платформу поверх Java или другой язык. Как и Скала, JRuby, что угодно. Многие просто верят, что СОЛНЦЕ было правильно.

2
ответ дан Michael-O 27 November 2013 в 02:11
поделиться

Проверенные исключения в своей первоначальной форме были попыткой устранить непредвиденные обстоятельства, а не сбои. Похвальной целью было выделить конкретные предсказуемые точки (невозможно подключиться, файл не найден и т. Д.) & Amp; убедитесь, что разработчики справились с этим.

То, что никогда не было включено в первоначальную концепцию, заключалось в том, чтобы заставить широкий спектр системных & amp; неисправимые ошибки, которые будут объявлены. Эти сбои никогда не были правильными, чтобы быть объявленными как проверенные исключения.

Сбои, как правило, возможны в коде, а EJB, web & amp; Контейнеры Swing / AWT уже учитывают это, предоставляя внешний обработчик исключений «неудавшийся запрос». Самая основная правильная стратегия - откат транзакции & amp; вернуть ошибку.

Одним из важных моментов является то, что runtime & amp; проверенные исключения являются функционально эквивалентными. Не существует обработки или восстановления, которые могут делать проверенные исключения, чего не могут делать исключения во время выполнения.

Самый большой аргумент против «проверенных» исключений заключается в том, что большинство исключений нельзя исправить. Простой факт в том, что мы не владеем кодом / подсистемой, которая сломалась. Мы не можем видеть реализацию, мы не несем за нее ответственность и не можем ее исправить.

Если наше приложение не является БД, мы не должны пытаться исправить БД. Это нарушило бы принцип инкапсуляции .

Особенно проблематичными были области JDBC (SQLException) и RMI для EJB (RemoteException). Вместо выявления исправляемых непредвиденных обстоятельств в соответствии с первоначальной концепцией «проверенных исключений» эти широко распространенные проблемы принудительной системной надежности, которые на самом деле не устраняются,

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

У нас есть очевидная проблема в Java - требовать тысячи блоков без пробных попыток, при этом значительная часть (40% +) неправильно кодируется. Почти ни один из них не реализует никакой подлинной обработки или надежности, но накладывает большие накладные расходы на кодирование.

Наконец, «проверенные исключения» в значительной степени несовместимы с функциональным программированием на FP.

Их настойчивое требование «немедленно обрабатывать» противоречит как передовой практике «обработки с опозданием», так и любой структуре FP, которая абстрагирует циклы / или поток управления.

Многие люди говорят об «обработке» проверенных исключений, но говорят через свои шляпы. Продолжая после сбоя с нулевыми, неполными или неправильными данными, притвориться, что успех не обрабатывает ничего. Это халатность инженерии / надежности самой низкой формы.

Чистая неудача - самая основная правильная стратегия обработки исключения. Откат транзакции, запись ошибки & amp; Сообщения о «неудачном» ответе пользователю являются разумной практикой и, самое главное, предотвращают передачу неверных бизнес-данных в базу данных.

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

Наконец, гораздо предпочтительнее потерпеть неудачу, чем работать с неверными данными. Продолжение может вызвать вторичные ошибки, далекие от первоначальной причины & amp; сложнее отлаживать; или в конечном итоге приведет к ошибочным фиксации данных. За это людей увольняют.

См .:
- http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/

4
ответ дан Thomas W 27 November 2013 в 02:11
поделиться

Здесь один аргумент против контролируемых исключительных ситуаций (с joelonsoftware.com):

обоснование состоит в том, что я полагаю, что исключения не лучше, чем "goto's", который рассматривают вредным с 1960-х, в этом они создают резкий переход из одной точки кода другому. На самом деле они значительно хуже, чем goto's:

  • Они невидимы в исходном коде. При рассмотрении блока кода, включая функции, которые могут или не могут выдать исключения, нет никакого способа видеть, какие исключения могли бы быть выданы и от где. Это означает, что даже осторожная инспекция кода не показывает потенциальные ошибки.
  • Они создают слишком много возможных точек выхода для функции. Для написания правильного кода действительно необходимо думать о каждом возможном пути выполнения кода через функцию. Каждый раз Вы вызываете функцию, которая может повысить исключение и не ловит его на месте, Вы создаете возможности для неожиданных ошибок, вызванных функциями, которые завершились резко, оставив данные в непоследовательном состоянии или другие пути выполнения кода, о которых Вы не думали.
3
ответ дан finnw 27 November 2013 в 13:11
поделиться

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

Другая проблема с контролируемыми исключительными ситуациями состоит в том, что они имеют тенденцию неправильно использоваться. Идеальный пример этого находится в java.sql.Connection close() метод. Это может бросить SQLException , даже при том, что Вы уже имеете , явно указал , что Вы сделаны с Соединением. Что могла закрыть информация (), возможно передают это, Вы заботились бы о?

Обычно, когда я закрываю () соединение *, оно выглядит примерно так:

try {
    conn.close();
} catch (SQLException ex) {
    // Do nothing
}

кроме того, не запускайте меня на различных методах синтаксического анализа и NumberFormatException... TryParse.NET, который не выдает исключения, настолько легче использовать, это болезненно для возвращения к Java (мы используем и Java и C#, где я работаю).

* Как дополнительный комментарий, Connection.close PooledConnection () не делает даже близкий соединение, но все еще необходимо поймать должное SQLException к нему являющийся контролируемой исключительной ситуацией.

3
ответ дан Powerlord 27 November 2013 в 13:11
поделиться

Anders говорит о ловушках контролируемых исключительных ситуаций и почему он упустил их из C# в эпизод 97 радио Разработки программного обеспечения.

5
ответ дан Chuck Conway 27 November 2013 в 13:11
поделиться

Artima опубликовал интервью с одним из архитекторов.NET, Anders Hejlsberg, который остро страхует аргументы от контролируемых исключительных ситуаций. Короткий дегустатор:

пункт бросков, по крайней мере, способ, которым это реализовано в Java, не обязательно вынуждает Вас обработать исключения, но если Вы не обрабатываете их, он вынуждает Вас подтвердить точно, через который могли бы пройти исключения. Это требует, чтобы Вы или поймали объявленные исключительные ситуации или поместили их в Ваш собственный пункт бросков. Для работы вокруг этого требования люди делают смешные вещи. Например, они украшают каждый метод, "выдает Исключение". Это просто полностью побеждает функцию, и Вы просто заставили программиста записать больше gobbledy месива. Это не помогает никому.

22
ответ дан Le Dude 27 November 2013 в 13:11
поделиться
  • 1
    Я понимаю. Таким образом, я думаю, что должен буду назвать некоторый ajax для регистрации где-нибудь на сервере, кто подписался на Концентраторе. – Danillo Corvalan 21 October 2011 в 20:39

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

До сих пор, у меня есть он, нашел легче работать с кодовой базой с Контролируемыми исключительными ситуациями. Когда я использую чужой API, хорошо, что я вижу точно, какие состояния ошибки я могу ожидать, когда я назову код и обрабатываю их правильно, или путем входа, отображения или игнорирования (Да, существуют допустимые случаи для игнорирования исключений, таких как реализация ClassLoder). Это дает код, который я пишу возможности восстановиться. Все исключения на этапе выполнения, вплоть до которых я распространяю, они кэшируются и обрабатываются с некоторым универсальным кодом обработки ошибок. Когда я нахожу контролируемую исключительную ситуацию, которую я действительно не хочу обрабатывать на определенном уровне, или что я рассматриваю ошибку логики программирования, тогда я обертываю его в RuntimeException и позволяю ему пузырь. Никогда не глотайте исключение без серьезного основания (и серьезные основания для того, чтобы сделать, это довольно недостаточно)

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

Это - все, конечно, вопрос навыка разработчика и предпочтения. Оба способа запрограммировать и обработка ошибок могут быть одинаково эффективными (или непригодными), таким образом, я не сказал бы, что существует Один Путь.

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

14
ответ дан Mario Ortegón 27 November 2013 в 13:11
поделиться

Я думаю, что это - превосходный вопрос и нисколько не спорный. Я думаю, что сторонние библиотеки должны (в целом) бросить , снял флажок исключения. Это означает, что можно изолировать зависимости от библиотеки (т.е. Вы не должны или повторно бросать их исключения или бросок Exception - обычно плохая практика). Spring уровень DAO является превосходным примером этого.

, С другой стороны, исключения из базового API Java должны в целом быть проверены, если они могли когда-нибудь быть обработанными. Возьмите FileNotFoundException или (мой фаворит) InterruptedException. Эти условия должны почти всегда быть обработанными конкретно (т.е. Ваша реакция на InterruptedException не является тем же как Вашей реакцией на IllegalArgumentException). То, что Ваши исключения проверяются разработчики сил для размышления о том, управляемо ли условие или нет. (Тем не менее я редко видел InterruptedException обработанный правильно!)

Еще одна вещь - RuntimeException не всегда, "где разработчик получил что-то не так". Недопустимое исключение аргумента выдается, когда Вы пытаетесь создать enum использование valueOf и нет никакого enum из того имени. Это - не обязательно ошибка разработчиком!

2
ответ дан oxbow_lakes 27 November 2013 в 13:11
поделиться
  • 1
    возможно, необходим, чтобы включить base.savechanges в попытку cacth, только выполнить scope.complete, если base.savechanges перестали работать: catch e { scope.complete(); throw }. – dani herrera 4 July 2013 в 10:32

Ну, это не об отображении stacktrace или тихо катастрофическом отказе. Это о способности передать ошибки между слоями.

проблема с контролируемыми исключительными ситуациями, они поощряют людей глотать важные детали (а именно, класс исключений). Если Вы принимаете решение не глотать ту деталь, то необходимо продолжать добавлять объявления вызовов через целое приложение. Это означает 1) это, новый тип исключительной ситуации будет влиять на большое количество функциональных подписей и 2) Вас, может пропустить определенный экземпляр исключения, которое Вы на самом деле - хотите поймать (скажите открытие вторичного файла для функции, которая пишет данные в файл. Вторичный файл является дополнительным, таким образом, можно проигнорировать его ошибки, но потому что подпись throws IOException, легко пропустить это).

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

, Конечно, теперь мы должны специализировать обработку ошибок в более высоких уровнях, реализовав логику повторной попытки и такой. Все - AppSpecificException, тем не менее, таким образом, мы не можем сказать, "Если IOException брошен, повторите" или, "Если ClassNotFound брошен, прервитесь полностью". У нас нет надежного способа стать к настоящими исключение, потому что вещи повторно упаковываются снова и снова, поскольку они передают между нашим кодом и сторонним кодом.

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

я нашел, снова и снова, и в течение проекта я упомянул, та обработка исключений попадает в 3 категории:

  1. Выгода и дескриптор конкретный исключение. Это должно реализовать логику повторной попытки, например.
  2. Выгода и перебросок другой исключения. Все, что происходит здесь, обычно регистрируется, и обычно банальное сообщение как "Неспособный открыть $filename". Это ошибки, о которых Вы ничего не можете сделать; только более высокий уровень знает достаточно для обработки его.
  3. Выгода все и дисплей сообщение об ошибке. Это обычно в самом корне диспетчера и всего, что он делает он удостоверяется, что может передать ошибку вызывающей стороне с помощью механизма неисключения (раскрывающийся диалог, упорядочив Ошибочный объект RPC, и т.д.).
45
ответ дан Carl Manaster 27 November 2013 в 13:11
поделиться
  • 1
    WOW... Я вошел эти SessionState прерывание, когда используется это с SignalR: stackoverflow.com/q/17768838/114029 Эй Damian: можно ли сказать мне, если эта рекомендация не использования SessionState включена в документы SignalR? It' d быть хорошим для помещения его там в центр деятельности как ПРЕДУПРЕЖДЕНИЕ!:) – Leniel Maccaferri 21 July 2013 в 10:38

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

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

И причина то, потому что, если она делает это, я должен зафиксировать ее, и я должен зафиксировать ее сразу же. Я хочу знать сразу, что существует проблема.

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

try {
  thirdPartyMethod();
} catch(TPException e) {
  // this should never happen
}

И я знаю, что можно сказать, что это - плохая практика, и что 'ответ' должен сделать что-то за исключением (позвольте мне предположить, зарегистрировать его?), но в Реальном мире (TM), большинство программистов просто не делает этого.

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

20
ответ дан tsimon 27 November 2013 в 13:11
поделиться
  • 1
    Что я don' t добираются, в моем проекте существует почти 20 классов информации пакета. Какой я должен добавить @XmlNs информацию? – hellzone 30 October 2013 в 15:46

Я думаю, что считал то же интервью Bruce Eckel, которое Вы сделали - и оно всегда прослушивало меня. На самом деле аргумент был приведен интервьюируемым (если это - действительно сообщение, Вы говорите о), Anders Hejlsberg, гений MS позади.NET и C#.

http://www.artima.com/intv/handcuffs.html

Вентилятор, хотя я имею Hejlsberg и его работу, этот аргумент, всегда казался мне поддельный. Это в основном сводится к:

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

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

Сводка сводки аргумента - то, что "Программисты не будут использовать их правильно, и не использование их правильно хуже, чем не наличие их".

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

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

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

Теперь программист API должен бояться бросать контролируемые исключительные ситуации повсеместно, или они будут просто раздражать клиентского программиста. Очень ленивый клиентский программист обратится к выгоде (Exception) {} поскольку Hejlsberg предупреждает, и все преимущество будет потеряно, и ад последует. Но при некоторых обстоятельствах, нет только никакой замены для хорошей контролируемой исключительной ситуации.

Для меня классическим примером является открытый для файла API. Каждый язык программирования в истории языков (в файловых системах, по крайней мере) имеет API где-нибудь, который позволяет Вам открыть файл. И каждый клиентский программист, использующий этот API, знает, что они должны иметь дело со случаем, что файл, который они пытаются открыть, не существует. Позвольте мне перефразировать это: Каждый клиентский программист, использующий этот API, должен знать, что они должны иметь дело с этим случаем. И существует протирание: может программист API помогать им знать, что они должны иметь дело с ним посредством комментария одного, или могут они действительно настаивать клиентское соглашение с ним.

В C идиома идет что-то как

  if (f = fopen("goodluckfindingthisfile")) { ... } 
  else { // file not found ...

где fopen указывает на отказ путем возврата 0, и C (по-дурацки) позволяет Вам рассматривать 0 как булевская переменная и... В основном Вы изучаете эту идиому, и Вы хорошо. Но что, если Вы - новичок и Вы не изучили идиому. Затем конечно, Вы начинаете с

   f = fopen("goodluckfindingthisfile");
   f.read(); // BANG! 

и научитесь на горьком опыте.

Обратите внимание, что мы только говорим о языках со строгим контролем типов здесь: существует четкое представление о том, что API находится на языке со строгим контролем типов: это - шведский стол функциональности (методы) для Вас для использования с ясно определенным протоколом для каждого.

То, что ясно определенный протокол обычно определяется сигнатурой метода. Здесь fopen требует, чтобы Вы передали его строка (или символ* в случае C). Если Вы даете ему что-то еще, что Вы получаете ошибку времени компиляции. Вы не следовали протоколу - Вы не используете API правильно.

На некоторых (неясных) языках тип возврата является частью протокола также. При попытке назвать эквивалент fopen() на некоторых языках, не присваивая его переменной Вы также получите ошибку времени компиляции (можно только сделать это с пустыми функциями).

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

(На динамически типизированном языке, как Ruby, можно передать что-либо, сказать плавание как имя файла - и это скомпилирует. Почему изводят пользователь с контролируемыми исключительными ситуациями, если Вы даже не собираетесь управлять аргументами метода. Аргументы, приведенные здесь, относятся к статически типизированным языкам только.)

Так, что относительно контролируемых исключительных ситуаций?

Хорошо вот одни из API Java, которые можно использовать для открытия файла.

try {
  f = new FileInputStream("goodluckfindingthisfile");
}
catch (FileNotFoundException e) {
  // deal with it. No really, deal with it!
  ... // this is me dealing with it
}

Видеть ту выгоду? Вот подпись для что метод API:

public FileInputStream(String name)
                throws FileNotFoundException

Отметьте это FileNotFoundException контролируемая исключительная ситуация.

Программист API говорит это Вам: "Можно использовать этого конструктора для создания нового FileInputStream, но Вас

a) должен передать в имени файла как Строка
b) должен принять возможность, что файл не мог бы быть найден во времени выполнения"

И это - самое главное, что касается меня.

Ключ в основном, что вопрос указывает как "Вещи, которые находятся вне контроля программиста". Моя первая мысль была то, что он имеет в виду вещи, которые находятся вне контроля программистов API. Но на самом деле, контролируемые исключительные ситуации при надлежащем использовании должны действительно быть для вещей, которые являются и вне клиентского программиста и вне управление программиста API. Я думаю, что это - ключ к не злоупотреблению контролируемыми исключительными ситуациями.

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

Таким образом, API делает это явным: будут случаи, где этот файл не существует в то время, когда Вы звоните мне, и у Вас были чертовски хорошо более выгодные условия с ним.

Это было бы более ясно со встречным иском. Предположите, что я пишу таблицу API. У меня есть модель таблицы где-нибудь с API включая этот метод:

public RowData getRowData(int row) 

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

public RowData getRowData(int row) throws CheckedInvalidRowNumberException

(Я действительно не назвал бы это "Проверенным", конечно.)

Это - плохое использование контролируемых исключительных ситуаций. Клиентский код будет полным вызовов для выборки данных строки, каждые из которых оказывается перед необходимостью использовать попытку/выгоду, и для какой? Они собираются сообщить пользователю, что неправильная строка разыскивалась? Вероятно, не - потому что независимо от того, что UI, окружающий мое табличное представление, это не должно позволять пользователю войти в состояние, где недопустимую строку требуют. Таким образом, это - ошибка со стороны клиентского программиста.

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

С контролируемой исключительной ситуацией в getRowData, это - ясно случай, который это собирается привести к ленивому программисту Hejlsberg, просто добавляющему пустые выгоды. Когда это произойдет, недопустимые значения строки не будут очевидны даже для тестера или отладки разработчика клиента, скорее они будут вести для стука - в ошибки, которые трудны точно определить источник. Ракеты Arianne аварийно завершатся после запуска.

Хорошо, таким образом, вот проблема: я говорю что контролируемая исключительная ситуация FileNotFoundException не просто хорошая вещь, но и существенный инструмент на панели инструментов программистов API для определения API самым полезным способом к клиентскому программисту. Но CheckedInvalidRowNumberException большое неудобство, ведя к плохому программированию и должно избежаться. Но как сказать различие.

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

  1. Из управления клиента или Закрытый по сравнению с Открытым:

    Контролируемые исключительные ситуации должны только использоваться, где ошибочный случай и вне контроля со стороны API и вне контроля со стороны клиентского программиста. Это имеет отношение, как открытый или закрылся, система. В ограниченном UI, где клиентский программист имеет контроль, скажем, надо всеми кнопками, команды клавиатуры и т.д., которые добавляют и удаляют строки из табличного представления (закрытая система), это - клиент, программирующий ошибку, если это пытается выбрать данные из несуществующей строки. В основанной на файле операционной системе, где любое число пользователей/приложений может добавить и удалить файлы (открытая система), возможно, что файл, который запрашивает клиент, был удален без их ведома, таким образом, они, как должны ожидать, будут иметь дело с ним.

  2. Повсеместность:

    Контролируемые исключительные ситуации не должны использоваться на вызове API, который часто делается клиентом. Часто я имею в виду от большого количества мест в клиентском коде - не часто вовремя. Таким образом, клиентский код не имеет тенденцию пытаться открыть тот же файл много, но мое табличное представление добирается RowData повсеместно из различных методов. В частности, я собираюсь быть записью большого количества кода как

    if (model.getRowData().getCell(0).isEmpty())
    

    и это будет болезненно для обертывания в попытке/выгоде каждый раз.

  3. Информирование пользователя:

    Контролируемые исключительные ситуации должны использоваться в случаях, где можно вообразить полезное сообщение об ошибке представленным конечному пользователю. Это "и что Вы сделаете, когда это произойдет?" вопрос я повысил выше. Это также касается объекта 1. Так как можно предсказать, что что-то за пределами системы клиентского API могло бы заставить файл не быть там, можно обоснованно сказать пользователю об этом:

    "Error: could not find the file 'goodluckfindingthisfile'"
    

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

    "Internal error occured: IllegalArgumentException in ...."
    

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

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

Извините, не означал делать это так долго и waffly. Позвольте мне закончить с двумя предложениями:

A: Программисты API: используйте контролируемые исключительные ситуации экономно для сохранения их полноценности. Когда в сомнении используют исключение непроверенное.

B: Клиентские программисты: привыкните создавать перенесенное исключение (погуглите его), вначале в Вашей разработке. JDK 1.4 и позже предоставляет конструктору в RuntimeException для этого, но можно легко создать собственное также. Вот конструктор:

public RuntimeException(Throwable cause)

Затем привыкните каждый раз, когда необходимо обработать контролируемую исключительную ситуацию, и Вы чувствуете себя ленивыми (или Вы думаете, что программист API был фанатичен в использовании контролируемой исключительной ситуации во-первых), только глотайте исключение, перенесите его и повторно бросьте его.

try {
  overzealousAPI(thisArgumentWontWork);
}
catch (OverzealousCheckedException exception) {
  throw new RuntimeException(exception);  
}

Поместите это в один из небольших шаблонов кода Вашего IDE и используйте его, когда Вы будете чувствовать себя ленивыми. Таким образом, если действительно необходимо обработать контролируемую исключительную ситуацию, Вы будете вынуждены возвратиться и иметь дело с нею после наблюдения проблемы во времени выполнения. Поскольку, верьте мне (и Anders Hejlsberg), Вы никогда не собираетесь возвращаться к этому TODO в Вашем

catch (Exception e) { /* TODO deal with this at some point (yeah right) */}
271
ответ дан 22 November 2019 в 23:11
поделиться

Действительно, контролируемые исключительные ситуации, с одной стороны, увеличивают устойчивость и правильность Вашей программы (Вы вынуждены сделать корректные объявления своих интерфейсов - исключения метод, броски являются в основном специальным типом возврата). С другой стороны, Вы сталкиваетесь с проблемой, что, начиная с исключений "пузырь", очень часто необходимо изменить много методов (все вызывающие стороны и вызывающие стороны вызывающих сторон, и так далее) при изменении исключений броски метода.

Контролируемые исключительные ситуации в Java не решают последнюю проблему; C# и VB.NET выводят ребенка с водой в ванне.

Хороший подход, который берет среднюю дорогу, описан в этой статье 2005 года OOPSLA (или связанный технический отчет.)

Короче говоря, это позволяет Вам говорить: method g(x) throws like f(x), что означает, что g выдает все исключения f броски. Вуаля, контролируемые исключительные ситуации без каскадной проблемы изменений.

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

6
ответ дан 22 November 2019 в 23:11
поделиться

Короче говоря:

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

Аргумент в пользу контролируемых исключительных ситуаций:

Для понимания, почему контролируемые исключительные ситуации не могли бы быть хорошей вещью давайте изменим к лучшему вопрос и спросите: Когда или почему контролируемые исключительные ситуации привлекательны, т.е. почему Вы хотели бы, чтобы компилятор осуществил объявление исключений?

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

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

В действительности, хотя, когда-либо слишком часто пакет com.acme только броски AcmeException вместо определенных подклассов. Вызывающие стороны затем должны обработать, объявить, или пересигнал AcmeExceptions, но все еще не может быть бесспорным ли AcmeFileNotFoundError произошедший или AcmePermissionDeniedError.

Таким образом, если Вы только интересуетесь AcmeFileNotFoundError, решение состоит в том, чтобы зарегистрировать запрос новых функций с программистами ВЫСШЕЙ ТОЧКИ и сказать им реализовывать, объявлять, и документировать тот подкласс AcmeException.

Итак, почему беспокойство?

Следовательно, даже с контролируемыми исключительными ситуациями, компилятор не может вынудить программистов выдать полезные исключения. Это - все еще просто вопрос качества API.

В результате языки без контролируемых исключительных ситуаций обычно не тарифицируют намного хуже. Программисты могли бы испытать желание бросить неопределенные экземпляры генерала Error класс, а не AcmeException, но если они будут заботиться вообще об их качестве API, то они будут учиться представлять AcmeFileNotFoundError в конце концов.

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

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

Также стоит отметить, что Java, VM не имеет контролируемых исключительных ситуаций - только компилятор Java, проверяет их, и файлы класса с измененными описаниями исключения совместимы во время выполнения. Java безопасность VM не улучшен контролируемыми исключительными ситуациями, только стиль кодирования.

19
ответ дан 22 November 2019 в 23:11
поделиться

Статья Effective Java Exceptions объясняет приятно, когда использовать неконтролируемый и когда использовать контролируемые исключительные ситуации. Вот некоторые кавычки от той статьи для выделения основных моментов:

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

Отказ: незапланированное условие, которое препятствует тому, чтобы метод достиг своей намеченной цели, которая не может быть описана независимо от внутренней реализации метода.

(ТАК не позволяет таблицы, таким образом, Вы могли бы хотеть считать следование из исходной страницы...),

Непредвиденное обстоятельство

  • Считается: часть дизайна
  • Как ожидают, произойдет: Регулярно, но редко
  • Кто заботится об этом: восходящий код, который вызывает метод
  • Примеры: Альтернативные режимы возврата
  • Лучше всего Отображение: контролируемая исключительная ситуация

Отказ

  • Считается: противное удивление
  • Как ожидают, произойдет: Никогда
  • Кто заботится об этом: люди, которые должны решить проблему
  • Примеры: Программируя ошибки, аппаратное неправильное функционирование, ошибки конфигурации, недостающие файлы, недоступные серверы
  • Лучше всего Отображение: исключение непроверенное
20
ответ дан 22 November 2019 в 23:11
поделиться

SNR

Во-первых, контролируемые исключительные ситуации уменьшают "отношение сигнал-шум" для кода. Anders Hejlsberg также говорит об императиве по сравнению с декларативным программированием, которое является подобным понятием. Так или иначе рассмотрите следующие фрагменты кода:

Обновите UI от не поток UI в Java:

try {  
    // Run the update code on the Swing thread  
    SwingUtilities.invokeAndWait(() -> {  
        try {
            // Update UI value from the file system data  
            FileUtility f = new FileUtility();  
            uiComponent.setValue(f.readSomething());
        } catch (IOException e) {  
            throw new UncheckedIOException(e);
        }
    });
} catch (InterruptedException ex) {  
    throw new IllegalStateException("Interrupted updating UI", ex);  
} catch (InvocationTargetException ex) {
    throw new IllegalStateException("Invocation target exception updating UI", ex);
}

Обновите UI от не поток UI в C#:

private void UpdateValue()  
{  
   // Ensure the update happens on the UI thread  
   if (InvokeRequired)  
   {  
       Invoke(new MethodInvoker(UpdateValue));  
   }  
   else  
   {  
       // Update UI value from the file system data  
       FileUtility f = new FileUtility();  
       uiComponent.Value = f.ReadSomething();  
   }  
}  

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

Повреждение тюрьмы

Для реализации даже самой основной из реализаций, таких как интерфейс List Java, контролируемые исключительные ситуации как инструмент для дизайна контракта падают. Рассмотрите список, который поддерживается базой данных или файловой системой или любой другой реализацией, которая бросает контролируемую исключительную ситуацию. Единственная возможная реализация должна поймать контролируемую исключительную ситуацию и повторно бросить ее как исключение непроверенное:

@Override
public void clear()  
{  
   try  
   {  
       backingImplementation.clear();  
   }  
   catch (CheckedBackingImplException ex)  
   {  
       throw new IllegalStateException("Error clearing underlying list.", ex);  
   }  
}  

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

Заключение

  • Ловля исключений отличается от обработки их.
  • Контролируемые исключительные ситуации добавляют шум к коду.
  • Обработка исключений работает хорошо в C# без них.

Я вел блог об этом ранее.

24
ответ дан 22 November 2019 в 23:11
поделиться

Вместо того, чтобы перехешировать весь (много) причины против контролируемых исключительных ситуаций, я выберу всего один. Я потерял счет количеству раз, которое я записал этому блоку кода:

try {
  // do stuff
} catch (AnnoyingcheckedException e) {
  throw new RuntimeException(e);
}

99% времени я ничего не могу делать с этим. Наконец блоки делают любую необходимую очистку (или по крайней мере они должны).

Я также потерял счет количеству раз, я видел это:

try {
  // do stuff
} catch (AnnoyingCheckedException e) {
  // do nothing
}

Почему? Поскольку кто-то должен был иметь дело с ним и был ленив. Это было неправильно?Конечно. Это происходит? Абсолютно. Что, если это было исключением непроверенным вместо этого? Приложение просто умерло бы (который предпочтителен для глотания исключения).

И затем у нас есть приводящий в бешенство код, который использует исключения в качестве формы управления потоком, как java.text. Формат делает. Bzzzt. Неправильно. Пользователь, помещающий "abc" в числовое поле на форме, не является исключением.

Хорошо, я предполагаю, что это было тремя причинами.

75
ответ дан 22 November 2019 в 23:11
поделиться

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

Вся эта мысль об исключениях состоит в том, что ошибка, брошенная где-нибудь путь вниз цепочка вызовов, может пузыриться и быть обработана кодом где-нибудь далее без прошедшего кода, имеющего необходимость волноваться об этом. Контролируемые исключительные ситуации, с другой стороны, требуют, чтобы каждый уровень кода между метателем и ловцом объявил, что они знают обо всех формах исключения, которое может пройти их. Это действительно мало отличается на практике от того, если контролируемые исключительные ситуации были просто специальными возвращаемыми значениями, на которые должна была проверить вызывающая сторона. например, [псевдокод]:

public [int or IOException] writeToStream(OutputStream stream) {
    [void or IOException] a= stream.write(mybytes);
    if (a instanceof IOException)
        return a;
    return mybytes.length;
}

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

Проблема состоит в том, что много кода, включая большой обматывает стандартной библиотеки, контролируемых исключительных ситуаций неправильного употребления для реальных исключительных условий, что Вы могли бы очень хорошо хотеть схватить несколько уровней. Почему IOException не является RuntimeException? На любом языке я могу позволить исключению IO произойти, и если я не сделаю ничего для обработки его, то мое приложение остановится, и я заставлю удобное отслеживание стека смотреть на. Это - лучшая вещь, которая может произойти.

Возможно, два метода от примера Вы хотите поймать весь IOExceptions от целого процесса записи к потоку, прервать процесс и вскочить в код сообщения об ошибке; в Java Вы не можете сделать этого, не добавляя ‘броски IOException’ на каждом уровне вызова, даже уровни, которые сами не делают никакого IO. Такие методы не должны need to знать об обработке исключений; необходимость добавить исключения к их подписям:

  1. излишне связь увеличений;
  2. делает интерфейсные подписи очень хрупкими для изменения;
  3. делает код менее читаемым;
  4. является столь раздражающим, что это, общая реакция программиста состоит в том, чтобы победить систему путем выполнения чего-то ужасного как, ‘выдает Исключение’, ‘выгода (Исключение e) {}’, или обертывание всего в RuntimeException (который делает отладку тяжелее).

И затем существует много просто смешных исключений библиотеки как:

try {
    httpconn.setRequestMethod("POST");
} catch (ProtocolException e) {
    throw new CanNeverHappenException("oh dear!");
}

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

Другой конкретный плохой эффект находится на Инверсии Управления, где компонент предоставления обратный вызов к универсальному компоненту B. Компонент A хочет смочь позволить исключению бросить от его обратного вызова назад к месту, где это назвало компонент B, но это не может, потому что это изменило бы интерфейс обратного вызова, который фиксируется B. Банка только делает это путем обертывания реального исключения в RuntimeException, который является еще большим количеством шаблона обработки исключений для записи.

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

181
ответ дан 22 November 2019 в 23:11
поделиться

Я много читал об обработке исключений, даже если (большую часть времени) я не могу сказать, что я счастлив или опечален существованием проверенных исключений, это мой вариант: проверено исключения в низкоуровневом коде (ввод-вывод, сеть, ОС и т. д.) и непроверенные исключения в высокоуровневых API / уровне приложений.

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

Проект, над которым я работаю, использует множество библиотек и объединяет их под одним и тем же API, API, который полностью основан на непроверенных исключениях. Эти фреймворки предоставляют высокоуровневый API, который вначале был полон проверенных исключений и имел только несколько непроверенных исключений (исключение инициализации, исключение конфигурации и т. Д.), И я должен сказать, что был не очень дружеский . В большинстве случаев вам приходилось перехватывать или повторно генерировать исключения, которые вы не знаете, как обрабатывать, или вам даже все равно (не путать с вами, игнорируйте исключения), особенно на стороне клиента, где один click может вызвать 10 возможных (проверенных) исключений.

Текущая версия (3-я) использует только непроверенные исключения и имеет глобальный обработчик исключений, который отвечает за обработку всего неперехваченного. API предоставляет способ регистрации обработчиков исключений, который решит, считается ли исключение ошибкой (в большинстве случаев это так), что означает регистрацию и уведомление кого-то, или это может означать что-то еще - например, это исключение, AbortException, что означает прерывание текущего потока выполнения и не Не регистрировать любую ошибку, потому что этого не следует делать. Конечно, чтобы проработать все пользовательские потоки, они должны обрабатывать метод run () с помощью try {...} catch (all).

public void run () {

try {
     ... do something ...
} catch (Throwable throwable) {
     ApplicationContext.getExceptionService().handleException("Handle this exception", throwable);
}

}

Это не необходимо, если вы используете WorkerService для планирования заданий (Runnable, Callable, Worker), который обрабатывает все за вас.

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

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

public void run () {

try {
     ... do something ...
} catch (Throwable throwable) {
     ApplicationContext.getExceptionService().handleException("Handle this exception", throwable);
}

}

Это не необходимо, если вы используете WorkerService для планирования заданий (Runnable, Callable, Worker), который обрабатывает все за вас.

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

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

public void run () {

try {
     ... do something ...
} catch (Throwable throwable) {
     ApplicationContext.getExceptionService().handleException("Handle this exception", throwable);
}

}

Это не необходимо, если вы используете WorkerService для планирования заданий (Runnable, Callable, Worker), который обрабатывает все за вас.

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

public void run () {

try {
     ... do something ...
} catch (Throwable throwable) {
     ApplicationContext.getExceptionService().handleException("Handle this exception", throwable);
}

}

В этом нет необходимости, если вы используете WorkerService для планирования заданий (Runnable, Callable, Worker), который обрабатывает все за вас.

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

public void run () {

try {
     ... do something ...
} catch (Throwable throwable) {
     ApplicationContext.getExceptionService().handleException("Handle this exception", throwable);
}

}

В этом нет необходимости, если вы используете WorkerService для планирования заданий (Runnable, Callable, Worker), который обрабатывает все за вас.

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

0
ответ дан 22 November 2019 в 23:11
поделиться

Как уже было сказано, проверенные исключения не не существует в байт-коде Java. Это просто механизм компилятора, не похожий на другие проверки синтаксиса. Я вижу проверенные исключения так же, как и компилятор, жалующийся на избыточное условие: if (true) {a; } b; . Это полезно, но я мог бы сделать это специально, поэтому позвольте мне проигнорировать ваши предупреждения.

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

Исправьте плохие программы! Не пытайтесь исправить язык, чтобы они не позволяли! Для большинства людей "

5
ответ дан 22 November 2019 в 23:11
поделиться

Хорошо ... Проверенные исключения не идеальны и имеют некоторые оговорки, но они служат цели. При создании API существуют определенные случаи отказов, которые предусмотрены этим API. В контексте строго статически типизированного языка, такого как Java, если кто-то не использует проверенные исключения, тогда нужно полагаться на специальную документацию и соглашения, чтобы сообщить о возможности ошибки. Это лишает вас всех преимуществ, которые компилятор может вызвать при обработке ошибок, и вы полностью оставлены на усмотрение программистов.

Таким образом, удаляется исключение Checked, как это было сделано в C #, как тогда можно программно и структурно передать возможность ошибки? Как сообщить клиентскому коду, что могут возникать такие-то ошибки и с ними нужно бороться?

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

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

Многие утверждали, что невозможность загрузить файл почти всегда была концом света для процесса, и он должен умереть ужасная и мучительная смерть. Так что да .. конечно ... хорошо .. вы создаете API для чего-то, и он в какой-то момент загружает файл ... Я, как пользователь указанного API, могу только ответить ... «Кто, черт возьми, вы такой, чтобы решать, когда моя программа должна вылететь! Конечно Учитывая выбор, при котором исключения поглощаются и не оставляют следов, или исключение EletroFlabbingChunkFluxManifoldChuggingException с трассировкой стека глубже траншеи Марианны, я бы выбрал последнее без малейших колебаний, но означает ли это, что это желательный способ справиться с исключением ? Разве мы не можем быть где-то посередине, где исключение будет преобразовываться и упаковываться каждый раз, когда оно переходит на новый уровень абстракции, чтобы оно действительно что-то значило?

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

6
ответ дан 22 November 2019 в 23:11
поделиться

Моя запись на c2.com все еще в основном не изменилась по сравнению с исходной формой: CheckedExceptionsAreIncompatibleWithVisitorPattern

В итоге:

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

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

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

Что касается основной проблемы:

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

4
ответ дан 22 November 2019 в 23:11
поделиться
Другие вопросы по тегам:

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