Создать настраиваемое исключение в Java

1. Введение

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

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

2. Необходимость специальных исключений

Исключения Java охватывают почти все общие исключения, которые неизбежно возникают при программировании.

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

Основными причинами введения настраиваемых исключений являются:

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

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

3. Пользовательское проверенное исключение

Проверенные исключения - это исключения, которые необходимо обрабатывать явно.

Рассмотрим фрагмент кода, который возвращает первую строку файла:

try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) return file.nextLine(); } catch(FileNotFoundException e) { // Logging, etc } 

Приведенный выше код представляет собой классический способ обработки проверенных Java исключений. Хотя код выдает исключение FileNotFoundException, неясно, какова точная причина - файл не существует или имя файла недействительно.

Чтобы создать собственное исключение, мы должны расширить класс java.lang.Exception .

Давайте посмотрим на пример этого, создав настраиваемое проверяемое исключение под названием IncorrectFileNameException:

public class IncorrectFileNameException extends Exception { public IncorrectFileNameException(String errorMessage) { super(errorMessage); } } 

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

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

Затем давайте посмотрим, как мы можем использовать настраиваемое исключение в нашем примере:

try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) return file.nextLine(); } catch (FileNotFoundException e) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException("Incorrect filename : " + fileName ); } //... } 

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

Чтобы исправить это, мы также можем добавить в конструктор параметр java.lang.Throwable . Таким образом, мы можем передать корневое исключение вызову метода:

public IncorrectFileNameException(String errorMessage, Throwable err) { super(errorMessage, err); } 

Теперь исключение IncorrectFileNameException используется вместе с основной причиной исключения следующим образом:

try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) { return file.nextLine(); } } catch (FileNotFoundException err) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); } // ... } 

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

4. Пользовательское исключение без отметки.

В нашем же примере предположим, что нам нужно настраиваемое исключение, если имя файла не содержит расширения.

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

Чтобы создать собственное непроверенное исключение, нам нужно расширить класс java.lang.RuntimeException :

public class IncorrectFileExtensionException extends RuntimeException { public IncorrectFileExtensionException(String errorMessage, Throwable err) { super(errorMessage, err); } } 

Следовательно, мы можем использовать это настраиваемое исключение без проверки в нашем примере:

try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) { return file.nextLine(); } else { throw new IllegalArgumentException("Non readable file"); } } catch (FileNotFoundException err) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); } //... } catch(IllegalArgumentException err) { if(!containsExtension(fileName)) { throw new IncorrectFileExtensionException( "Filename does not contain extension : " + fileName, err); } //... } 

5. Заключение

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

Код примеров, использованных в этой статье, доступен на Github.