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


213

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

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


11
Барри Рузек написал превосходное руководство по выбору проверенных или непроверенных исключений.
Sigget

Ответы:


241

Проверенные исключения велики, если вы понимаете, когда их следует использовать. API ядра Java не соблюдает эти правила для SQLException (а иногда и для IOException), поэтому они так ужасны.

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

Непроверенные исключения должны быть использованы для всего остального.

Я сломаю это для вас, потому что большинство людей неправильно понимают, что это значит.

  1. Предсказуемый, но непредсказуемый : вызывающий сделал все, что в его силах, для проверки входных параметров, но какое-то условие вне их контроля вызвало сбой операции. Например, вы пытаетесь прочитать файл, но кто-то удаляет его между временем, когда вы проверяете, существует ли он, и временем начала операции чтения. Объявляя проверенное исключение, вы говорите вызывающей стороне предвидеть этот сбой.
  2. Разумное восстановление после : нет смысла говорить вызывающим абонентам ожидать исключений, которые они не могут восстановить. Если пользователь пытается прочитать из несуществующего файла, вызывающая сторона может запросить у них новое имя файла. С другой стороны, если метод завершается неудачей из-за программной ошибки (неверные аргументы метода или ошибочная реализация метода), приложение ничего не может сделать, чтобы устранить проблему в середине выполнения. Лучшее, что он может сделать - зарегистрировать проблему и подождать, пока разработчик не исправит ее позже.

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

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

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


2
«Вы пытаетесь прочитать файл, но кто-то удаляет его между моментом проверки, существует ли он, и временем начала операции чтения». => Как это вообще «ожидается»? Для меня это звучит так: неожиданно и предотвратимо. Кто будет ожидать, что файл будет удален только между двумя утверждениями?
Корай Тугай

9
@KorayTugay Ожидаемый не означает, что сценарий является типичным. Это просто означает, что мы можем предвидеть эту ошибку, возникающую раньше времени (по сравнению с ошибками программирования, которые нельзя предсказать заранее). Unpreventable относится к тому факту, что программист ничего не может сделать, чтобы запретить пользователю или другим приложениям удалять файл между временем, когда мы проверяем, существует ли он, и временем начала операции чтения.
Гили

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

59

От ученика Java :

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

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

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


13
Это православный взгляд. Но есть много противоречий по этому поводу.
artbristol

49

Правило, которое я использую: никогда не используйте непроверенные исключения! (или когда ты не видишь никакого пути вокруг этого)

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


3
ИМХО, проверенные исключения могли бы быть основным преимуществом, если бы у метода был простой способ объявить, что он не ожидает, что методы, вызываемые в определенном блоке кода, генерируют определенные исключения (или вообще вообще), и что любой проверенный исключения, которые бросаются вопреки такому ожиданию, должны быть обернуты в некоторый другой тип исключения и переброшены. Я бы предположил, что в 90% случаев, когда код не готов справиться с проверенным исключением, такой перенос и повторное отбрасывание был бы лучшим способом его обработки, но из-за отсутствия языковой поддержки это делается редко.
суперкат

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

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

@supercat: у кода уже есть простой способ сделать то, что вы хотите в первом комментарии: заключить код в блок try, перехватить Exception, а Exception в RuntimeException и перебросить.
Уоррен Роса

1
@KonradRudolph суперкат ссылается на «конкретный блок кода»; учитывая, что блок должен быть определен, декларативный синтаксис не будет значительно уменьшать раздувание. Если вы думаете, что это будет декларативно для всей функции, это будет поощрять плохое программирование, поскольку люди будут просто придерживаться декларации вместо того, чтобы фактически смотреть на проверенные исключения, которые потенциально могут быть перехвачены, и следить за тем, чтобы не было другого лучшего способа. справиться с ними.
Уоррен Роса

46

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

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

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

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

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

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


3
Это очень близко к userstories.blogspot.com/2008/12/…
alexsmail

16
@alexsmail Интернет никогда не перестает меня удивлять, на самом деле это мой блог :)
Stephane

30

Ты прав.

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

Например:

/**
 * @params operation - The operation to execute.
 * @throws IllegalArgumentException if the operation is "exit"
 */
 public final void execute( String operation ) {
     if( "exit".equals(operation)){
          throw new IllegalArgumentException("I told you not to...");
     }
     this.operation = operation; 
     .....  
 }
 private void secretCode(){
      // we perform the operation.
      // at this point the opreation was validated already.
      // so we don't worry that operation is "exit"
      .....  
 }

Просто чтобы привести пример. Дело в том, что если система быстро выходит из строя, то вы будете знать, где и почему она не сработала. Вы получите трассировку стека, как:

 IllegalArgumentException: I told you not to use "exit" 
 at some.package.AClass.execute(Aclass.java:5)
 at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
 ar ......

И ты узнаешь, что случилось. OtherClass в методе "DelegateTheWork" (в строке 4569) вызвал ваш класс со значением "exit", даже если это не так и т. Д.

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

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

 public static MyClass createInstane( Object data1, Object data2 /* etc */ ){ 
      if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }

  }


  // the rest of the methods don't validate data1 anymore.
  public void method1(){ // don't worry, nothing is null 
      ....
  }
  public void method2(){ // don't worry, nothing is null 
      ....
  }
  public void method3(){ // don't worry, nothing is null 
      ....
  }

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

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

Если проверенное исключение чрезмерно используется (добавление «throw Exception» во все сигнатуры методов), тогда ваш код станет очень хрупким, потому что все будут игнорировать это исключение (потому что оно слишком общее), и качество кода будет серьезно скомпрометированы.

Если вы злоупотребите непроверенным исключением, произойдет нечто подобное. Пользователи этого кода не знают, если что-то пойдет не так, появится много попыток {...} catch (Throwable t).


2
Хорошо сказано! +1. Меня всегда удивляет, что различие вызывающий абонент (не проверено) / вызываемый (проверено) не является более очевидным ...
VonC

19

Вот мое «последнее правило».
Я использую:

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

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


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

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

  • ДОЛЖЕН существовать контейнер объекта для создания / получения (ответственность за
    непроверенное исключение CALLER => и очистить комментарий javadoc для этой вызываемой функции)
  • другие параметры не могут быть нулевыми
    (выбор кодера для помещения его в CALLER: кодер не будет проверять нулевой параметр, но кодер ДОКУМЕНТИТ ЭТО)
  • результат не может быть пустым
    (ответственность и выбор кода вызываемого абонента, выбор, который будет представлять большой интерес для
    проверяемого исключения вызывающего абонента =>, поскольку каждый вызывающий абонент ДОЛЖЕН принять решение, если объект не может быть создан / найден, и что решение должно быть исполнено во время компиляции: они не могут использовать эту функцию без необходимости иметь дело с этой возможностью, то есть с этим проверенным исключением).

Пример:


/**
 * Build a folder. <br />
 * Folder located under a Parent Folder (either RootFolder or an existing Folder)
 * @param aFolderName name of folder
 * @param aPVob project vob containing folder (MUST NOT BE NULL)
 * @param aParent parent folder containing folder 
 *        (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob)
 * @param aComment comment for folder (MUST NOT BE NULL)
 * @return a new folder or an existing one
 * @throws CCException if any problems occurs during folder creation
 * @throws AssertionFailedException if aParent is not in the same PVob
 * @throws NullPointerException if aPVob or aParent or aComment is null
 */
static public Folder makeOrGetFolder(final String aFoldername, final Folder aParent,
    final IPVob aPVob, final Comment aComment) throws CCException {
    Folder aFolderRes = null;
    if (aPVob.equals(aParent.getPVob() == false) { 
       // UNCHECKED EXCEPTION because the caller failed to live up
       // to the documented entry criteria for this function
       Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); }

    final String ctcmd = "mkfolder " + aComment.getCommentOption() + 
        " -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName);

    final Status st = getCleartool().executeCmd(ctcmd);

    if (st.status || StringUtils.strictContains(st.message,"already exists.")) {
        aFolderRes = Folder.getFolder(aFolderName, aPVob);
    }
    else {
        // CHECKED EXCEPTION because the callee failed to respect his contract
        throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'");
    }
    return aFolderRes;
}

19

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

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

Это философия, используемая многими системами. В частности, приходят на ум Spring и Hibernate - они преобразуют известное проверенное исключение в непроверенное исключение именно потому, что проверенные исключения чрезмерно используются в Java. Одним из примеров, который я могу вспомнить, является JSONException от json.org, который является проверенным исключением и в основном раздражает - его следует отключить, но разработчик просто не продумал его.

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


13

Вот очень простое решение вашей проверенной / непроверенной дилеммы.

Правило 1. Думайте о непроверенном исключении как о тестируемом условии перед выполнением кода. например…

x.doSomething(); // the code throws a NullPointerException

где х нуль ... ... код должен иметь следующее ...

if (x==null)
{
    //do something below to make sure when x.doSomething() is executed, it won’t throw a NullPointerException.
    x = new X();
}
x.doSomething();

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

Socket s = new Socket(“google.com”, 80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();

… В приведенном выше примере URL (google.com) может быть недоступен из-за неработоспособности DNS-сервера. Даже в тот момент, когда DNS-сервер работал и преобразовал имя «google.com» в IP-адрес, если в любой момент после подключения к google.com сеть может выйти из строя. Вы просто не можете все время проверять сеть перед чтением и записью в потоки.

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

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

Здесь есть серая зона. В случае, если требуется много тестов (ошеломляющее утверждение if с большим количеством && и ||), генерируемое исключение будет CheckedException просто потому, что слишком много боли, чтобы получить право - вы просто не можете сказать эту проблему это ошибка программирования. Если тестов намного меньше 10 (например, «if (x == null)»), то ошибка программиста должна быть UncheckedException.

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

2 приведенных выше правила, вероятно, уберут 90% вашего беспокойства, из которого можно выбирать. Чтобы суммировать правила, следуйте этому шаблону… 1) если выполняемый код может быть проверен перед тем, как он будет выполнен, чтобы он выполнялся правильно, и если возникает Исключение - то есть ошибка программиста, то Исключением должно быть UncheckedException (подкласс RuntimeException). ). 2) если код, который должен быть выполнен, не может быть протестирован, прежде чем он будет выполнен для правильной работы, исключение должно быть проверенным исключением (подкласс исключения).


9

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


1
+1 Следует отметить, что модульные тесты могут быть лучшим способом решения проблемы, для решения которой предназначены проверенные исключения.
Кит Пинсон

+1 за юнит-тестирование. Использование проверенных / непроверенных исключений мало влияет на качество кода. Таким образом, аргумент, что если использовать проверенные исключения, это приведет к лучшему качеству кода, это полный фиктивный аргумент!
user1697575

7

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

Непроверенное исключение: если клиент не может ничего сделать после исключения, тогда вызовите непроверенное исключение.

Пример: Если вы должны выполнять арифметическую операцию в методе A () и на основе выходных данных из A (), вам нужно выполнить другую операцию. Если выходные данные из метода A () являются нулевыми, чего вы не ожидаете во время выполнения, то ожидается, что вы получите исключение нулевого указателя, которое является исключением времени выполнения.

Обратитесь сюда


2

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

Я считаю проверенные исключения полезными на нижнем уровне, как детали реализации. Часто кажется, что механизм управления потоком данных лучше, чем управлять заданным ошибочным «кодом возврата». Иногда это может помочь увидеть влияние идеи на низкоуровневое изменение кода тоже ... объявить проверенное исключение в нисходящем направлении и посмотреть, кого нужно будет скорректировать. Этот последний пункт не применяется, если есть много общего: catch (Exception e) или throws Exception, которое обычно не слишком хорошо продумано в любом случае.


2

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

  1. Проверено исключение. Это часть бизнес-прецедента или потока вызовов, это часть логики приложения, которую мы ожидаем или не ожидаем. Например, соединение отклонено, условие не выполнено и т. Д. Мы должны обработать его и показать пользователю соответствующее сообщение с инструкциями, что произошло и что делать дальше (повторите попытку позже и т. Д.). Я обычно называю это исключением пост-обработки или "пользовательским" исключением.

  2. Непроверенное исключение. Это является частью исключения из программирования, некоторой ошибкой в ​​программировании программного кода (ошибка, дефект) и отражает то, как программисты должны использовать API согласно документации. Если внешний документ lib / framework сообщает, что ожидает получить данные в некотором диапазоне и не в нулевом, потому что будет выброшено исключение NPE или IllegalArgumentException, программист должен ожидать его и правильно использовать API в соответствии с документацией. В противном случае будет выдано исключение. Я обычно называю это исключением предварительной обработки или исключением «проверки».

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

  1. Проверено исключение. Целевая аудитория - пользователи / клиенты.
  2. Непроверенное исключение. Целевая аудитория - разработчики. Другими словами, непроверенное исключение предназначено только для разработчиков.

По этапу жизненного цикла разработки приложения.

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

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


2

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

  • Если ошибка является ошибкой программиста, это должно быть непроверенное исключение . Например: SQLException / IOException / NullPointerException. Эти исключения являются ошибками программирования. Они должны быть обработаны программистом. В то время как в JDBC API SQLException является проверенным исключением, в Spring JDBCTemplate это непроверенное исключение. Программист не беспокоится о SqlException при использовании Spring.
  • Если ошибка не является ошибкой программиста, а ее причина исходит из внешнего источника, это должно быть проверенное исключение. Например: если файл удален или разрешение на изменение файла кем-то другим, его следует восстановить.

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

Проверенное исключение может быть обработано двумя способами. Они используют try-catch или распространяют исключение. В случае распространения исключения все методы в стеке вызовов будут тесно связаны из-за обработки исключения. Вот почему мы должны использовать Checked Exception осторожно.

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


1

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

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


Я не согласен с вашим утверждением «непроверенные исключения используются редко, если вообще используются», на самом деле должно быть наоборот! Используйте непроверенные исключения по умолчанию при разработке иерархии исключений приложения. Позвольте разработчикам решить, когда они хотят обработать исключение (например, они не обязаны помещать блоки catch или предложение throws, если они не знают, как его обработать).
user1697575

1

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

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

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

Исключение во время выполнения используется, когда исключение, скорее всего, произошло, нет пути идти дальше, и ничто не может быть восстановлено. Таким образом, в этом случае мы можем принять меры предосторожности в отношении этого исключения. Пример: NUllPointerException, ArrayOutofBoundsException. Это с большей вероятностью произойдет. В этом сценарии мы можем принять меры предосторожности при кодировании, чтобы избежать такого исключения. В противном случае мы должны будем написать try catch и везде блоки.

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


1

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

почему происходит исключение? Что мы можем сделать, когда это произойдет

по ошибке ошибка. такой как метод нулевого объекта называется.

String name = null;
... // some logics
System.out.print(name.length()); // name is still null here

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

с помощью внешнего ввода вы не можете контролировать или доверять выходу внешнего сервиса.

String name = ExternalService.getName(); // return null
System.out.print(name.length());    // name is null here

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

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

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

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

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

В этом случае нам нужно знать, что за исключение произошло в ExternalService? Это зависит:

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

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


0

Я думаю, что при объявлении Application Exception это должно быть Unchecked Exception, то есть подкласс RuntimeException. Причина в том, что он не будет загромождать код приложения try-catch и выдает объявление метода. Если ваше приложение использует Java Api, который выдает проверенные исключения, которые в любом случае необходимо обрабатывать. В других случаях приложение может выдать непроверенное исключение. Если вызывающему приложению все еще нужно обработать непроверенное исключение, это можно сделать.


-12

Правило, которое я использую: никогда не используйте непроверенные исключения! (или когда ты не видишь никакого пути вокруг этого)

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

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


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

Полностью не согласен с вашим не аргументированным ответом: «никогда не используйте непроверенные исключения»
user1697575
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.