Почему люди Java часто используют исключения тихо? [закрытый]

Другой способ обновить (сложным способом) страницу в угловом 2, например, это выглядит как f5

import { Location } from '@angular/common';

constructor(private location: Location) {}

pageRefresh() {
   location.reload();
}
76
задан Michael Myers 24 December 2014 в 17:27
поделиться

28 ответов

Я всегда думал, что это похоже на следующий сценарий:

«В человека стреляют.

Он задерживает дыхание и имеет достаточно сил, чтобы сесть на автобус.

Через 10 миль мужчина выходит из автобуса, проходит пару кварталов и умирает ».

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

Лучше:

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

Когда прибывает полиция, все улики на месте.

Если система должна выйти из строя, лучше дать сбой быстро

Ответ на вопрос:

  1. Незнание.
      +
  2. Ленивец

РЕДАКТИРОВАТЬ:

Конечно, секция улова полезна.

Если что-то можно сделать с исключением, то это должно быть сделано.

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

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

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

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

Теперь для проверенных исключений, которые нельзя восстановить, но которые являются критическими (обычно из-за ошибок программирования), не проглатывайте их. Я думаю, что исключения должны регистрироваться как можно ближе к источнику проблемы, поэтому я бы не рекомендовал удалять вызов printStackTrace (). Вы захотите превратить их в RuntimeException с единственной целью - не объявлять эти исключения в своем бизнес-методе. На самом деле это не так Имеет смысл иметь высокоуровневые бизнес-методы, такие как createClientAccount (), выдает исключение ProgrammingErrorException (читайте SQLException), вы ничего не можете сделать, если у вас есть опечатки в вашем sql или доступ к плохим индексам.

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

Может быть много причин, по которым можно использовать исключение catch. Во многих случаях это плохая идея, потому что вы также ловите RuntimeExceptions - и вы не знаете, в каком состоянии будут находиться базовые объекты после того, как это произойдет? Это всегда трудная вещь с неожиданными условиями: можете ли вы быть уверены, что остальная часть кода впоследствии не откажет.

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

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

I think developers also try to consider the importance of "doing the right thing" in a particular context. Often times for throw away code or when propagating the exception upwards wouldn't buy anything because the exception is fatal, you might as well save time and effort by "doing the wrong thing".

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

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

-2
ответ дан 24 November 2019 в 11:02
поделиться

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

Я вообще-то увлекаюсь Fail-Fast / Fail-HARD, но хотя бы распечатайте это. Если вы на самом деле "съедите" исключение (то есть по-настоящему ничего не делать: {}), это будет стоить кому-то ДНЕЙ, чтобы найти его.

Проблема в том, что Java вынуждает вас ловить много вещей, которые разработчик знает, что победит ' не быть брошенными, или им все равно, если они. Самый распространенный - Thread.sleep (). Я понимаю, что здесь есть дыры, которые могут привести к проблемам с потоками, но обычно вы знаете, что не прерываете его. Период.

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

If you want your exception to be handled outside the scope of the current method you don't need to to catch it actually, instead you add 'throws' statement to the method signature.

The try/catch statements that you've seen are only in the code where programmer explicitly decided to handle the exception in place and therefore not to throw it further.

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

Его ленивая практика - не что иное, как на самом деле.

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

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

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

Если вы обнаружите это в чем-либо, кроме примера кода, не стесняйтесь пересылать код на TDWTF,

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

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

Причина: реализация интерфейса не может генерировать (проверенные) исключения, кроме тех, которые определены в спецификации интерфейса. По этой причине создатели интерфейса, не зная, каким методам класса, реализующего интерфейс, может действительно потребоваться сгенерировать исключение, могут указать, что все методы могут вызывать по крайней мере один тип исключения. Пример: JDBC, где объявлено, что все и его «бабушка» выбрасывают SQLException.

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

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

Как уже отмечалось, вызов printStackTrace () на самом деле не является тихой обработкой.

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

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

Он потребляется молча, только если блок catch действительно пуст.

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

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

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

В C # все исключения являются исключениями времени выполнения, но в Java у вас есть исключения времени выполнения и проверенные исключения, которые вы должны либо перехватить, либо объявить в ваших методах. Если вы вызываете какой-либо метод, у которого в конце есть «throws», вы должны либо перехватить упомянутые исключения, либо ваш метод также должен объявить эти исключения.

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

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

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

  • «Этого не произойдет!» Конечно, когда-нибудь вы «знаете», что этого Исключения не произойдет, но еще более целесообразно повторно вызвать исключение времени выполнения с возникшим Исключением в качестве «причины», а не просто игнорировать его. Бьюсь об заклад, это произойдет когда-нибудь в будущем. ; -)

  • Код прототипа Если вы просто набираете свои данные, чтобы посмотреть, сработает ли это, вы можете игнорировать все исключения, которые могут произойти. Это единственный случай, когда я делаю ленивый улов (Throwable). Но если из кода получится что-то полезное, я включаю правильную обработку исключений.

  • «Я не знаю, что делать!» Я видел много кода, особенно библиотечного, который поглощает возникающие исключения, потому что на этом уровне приложения невозможно выполнить надлежащую обработку. НЕ ДЕЛАЙТЕ ЭТОГО! Просто повторно вызовите исключение (либо добавив предложение throws в сигнатуру метода, либо заключив исключение в конкретную библиотеку).

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

A System.out print or e.printStackTrace() - which implies use of System.out is usually a red flag meaning someone didn't bother to do a diligent job. Excepting desktop Java Applications, most Java apps are better off using logging.

If the failure mode for a method is a no-operation, it's perfectly fine to eat an exception, whether you record the reason (and existence) or not. More typically, however, the catch clause should be taking some sort of exceptional action.

Rethrowing an exception is something that's best done when you either use the catch to clean up part of the work at a level where the necessary information is still available or when you need to transform the exception to an exception type more amenable to the caller.

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

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

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

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

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

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

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

, потому что Проверенные исключения - это неудачный эксперимент

(возможно, printStackTrace () - настоящая проблема ? :)

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

Я нахожу, что это часто делается по 2 причинам

  1. Программист был ленив
  2. Программист хотел защитить точку входа в этот компонент (правильно или неправильно)

Я не верю это явление ограничено Java. Я часто видел такое кодирование в C # и VB.Net.

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

Foo* pFoo = ...;
pFoo->SomeMethod(); // Void or swallowing errors, who knows?

Этот код выглядит лучше, но если SomeMethod () скажет вернуть HResult, это будет семантически не отличаться от проглатывания исключения.

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

Это классический аргумент соломенного человека . printStackTrace () - это средство отладки. Если вы видели это в блоге или в журнале, это было потому, что автора больше интересовало проиллюстрировать другой пункт другой , чем обработка исключений. Если вы видели это в производственном коде, разработчик этого кода был невежественным или ленивым, не более того. Его не следует рассматривать как пример обычной практики в «мире Java».

19
ответ дан 24 November 2019 в 11:02
поделиться
  1. Java заставляет вас явно обрабатывать все исключения. Если метод, который вызывает ваш код, объявлен для генерации исключений FooException и BarException, ваш код ДОЛЖЕН обрабатывать (или генерировать) эти исключения. Единственным исключением является RuntimeException , которое молчит, как ниндзя.
  2. Многие программисты ленивы (включая меня), и очень легко просто распечатать трассировку стека.
19
ответ дан 24 November 2019 в 11:02
поделиться

Обычно это происходит из-за того, что IDE предлагает полезное «быстрое исправление», которое помещает проблемный код в блок try-catch с этой обработкой исключений. Идея в том, что вы действительно что-то делаете, а ленивые разработчики - нет.

Это, без сомнения, дурной тон.

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

Боюсь, что большинство java-программистов не знают, что делать с исключениями, и всегда считают это раздражением, которое замедляет их кодирование в «номинальном» случае. Конечно, они совершенно неправы, но их трудно убедить в том, что ЭТО ВАЖНО правильно обрабатывать исключения. Каждый раз, когда я сталкиваюсь с таким программистом (это случается часто), я даю ему две записи для чтения:

  • знаменитое «Мышление в java»
  • Короткую и интересную статью Барри Рузека можно найти здесь: www.oracle.com/technology/pub /articles/dev2arch/2006/11/effective-exceptions.html

Между прочим, я полностью согласен с тем, что глупо перехватывать типизированное исключение, чтобы повторно выбросить его, встроенное в исключение RuntimeException:

  • , если вы его поймаете, HANDLE
  • в противном случае измените подпись вашего метода, чтобы добавить возможные исключения, которые вы бы / не смогли обработать, чтобы у вызывающего абонента была возможность сделать это самостоятельно.
2
ответ дан 24 November 2019 в 11:02
поделиться

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

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

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


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

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

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

Как написать «правильный способ», чем?

  • Укажите каждый базовый класс исключений, которые могут быть добавлены заголовок метода. AFAICR Eclipse может делать это автоматически.
  • Сделайте список выдачи в прототипе метода значимым. Длинные списки бессмысленны, а "бросать исключение" лениво (но полезно, когда вы не беспокоитесь много об исключениях).
  • При написании "неправильного пути" простое "исключение исключения" намного лучше и принимает меньше байтов, чем "try {...} catch (Exception e) {e.printStackTrace ();}".
  • При необходимости повторно вызвать исключение в цепочке.
1
ответ дан 24 November 2019 в 11:02
поделиться

Как указывали другие, вы видите это по одной из трех причин:

  1. IDE сгенерировала блок try-catch
    • Код был скопирован и вставлен
    • Разработчик поместил трассировку стека для отладки, но так и не вернулся, чтобы обработать исключение должным образом

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

Лучшее описание того, что следует сделать в блоке catch, можно найти в главе 9 документа Effective Java Джошуа Блох .

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

Я не согласен с тем, что повторное создание проверенного исключения - лучшая идея. Обработка средств отлова; если вам нужно перебросить, вы не должны ловить. В этом случае я бы добавил предложение throws к сигнатуре метода.

Я бы сказал, что перенос проверенного исключения в непроверенное (например, способ, которым Spring переносит проверенное исключение SQLException в экземпляр своей непроверенной иерархии) приемлемо .

Ведение журнала можно считать обработкой. Если бы пример был изменен для записи трассировки стека с использованием log4j вместо записи в консоль, сделало бы это приемлемым? Не так много изменений, ИМО.

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

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

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

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

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

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

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

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

Кстати: если вы хотите повторно генерировать проверенное исключение, вы можете сделать это с помощью

try {
   // do something
} catch (Throwable e) {
   // do something with the exception
   Thread.currentThread().stop(e); // doesn't actually stop the current thread, but throws the exception/error/throwable
}

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

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

Поскольку они еще не изучили этот трюк:

class ExceptionUtils {
    public static RuntimeException cloak(Throwable t) {
        return ExceptionUtils.<RuntimeException>castAndRethrow(t);
    }

    @SuppressWarnings("unchecked")
    private static <X extends Throwable> X castAndRethrow(Throwable t) throws X {
        throw (X) t;
    }
}

class Main {
    public static void main(String[] args) { // Note no "throws" declaration
        try {
            // Do stuff that can throw IOException
        } catch (IOException ex) {
            // Pretend to throw RuntimeException, but really rethrowing the IOException
            throw ExceptionUtils.cloak(ex);
        }
    }
}
1
ответ дан 24 November 2019 в 11:02
поделиться
Другие вопросы по тегам:

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