Знайте свои исключения!

RedDeveloper
27.03.2023 11:58
Знайте свои исключения!

Что такое исключения?

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

Иерархия исключений

Все исключения в Java наследуются от класса Throwable. В иерархии исключений есть два основных типа: Error и Exception.

Ошибки - это исключительные условия, которые являются внешними по отношению к приложению и от которых приложение обычно не может оправиться. Примерами ошибок являются OutOfMemoryError и StackOverflowError.

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

Проверенные и непроверенные исключения

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

Время компиляции и время выполнения

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

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

Проверенные исключения

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

Например, допустим, вы пишете метод, который считывает файл с диска:

public String readFile(String filePath) throws IOException {
    // code to read file goes here
}

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

try {
    String contents = readFile("path/to/file.txt");
    // do something with contents
} catch (IOException e) {
    // handle the exception
}

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

Непроверенные исключения

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

Например, допустим, вы пишете метод, который делит два числа:

public int divide(int a, int b) {
    return a / b;
}

В этом примере, если b равно нулю, код во время выполнения выбросит java.lang.ArithmeticException. Это непроверенное исключение, поскольку компилятор не проверяет его во время компиляции.

int result = divide(10, 0); // throws ArithmeticException at runtime

Вывод:

Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.himani.Exceptions.main(Exceptions.java:5)

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

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

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

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

Создание собственных исключений

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

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

public class MyCheckedException extends Exception {
    // code for your custom exception goes here
}
public class MyUncheckedException extends RuntimeException {
    // code for your custom exception goes here
}

Обработка исключений в Spring Boot

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

Например, предположим, у нас есть REST-контроллер, который извлекает пользователя по ID:

@RestController
public class UserController {
    @Autowired
    private UserRepository userRepository;
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new UserNotFoundException(id));
    }
}

Если пользователь с указанным ID не существует, UserRepository выбросит исключение. Мы можем обработать это исключение, создав класс @ControllerAdvice:

@ControllerAdvice
public class UserControllerAdvice {
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException ex) {
        return ResponseEntity.notFound().build();
    }
}

Этот класс определяет метод-обработчик, который будет вызываться при возникновении исключения UserNotFoundException. Метод возвращает ResponseEntity с кодом состояния HTTP 404.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?

20.08.2023 18:21

Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией

20.08.2023 17:46

В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox

19.08.2023 18:39

Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest

19.08.2023 17:22

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

Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️

18.08.2023 20:33

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL

14.08.2023 14:49

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