Ви

Винятки у Java

25 вправ

Про концепцію Винятки

Мова програмування Java використовує винятки, щоб обробляти помилки та інші виняткові події.

Що таке виняток

Виняток - це подія, що виникає під час виконання програми й порушує нормальний потік інструкцій. У Java винятки виникають явно, і цю дію називають киданням винятку. А дію з обробки винятку називають перехопленням винятку.

У Java всі винятки є підкласами класу Exception, який, своєю чергою, є підкласом Throwable.

Java розрізняє два типи винятків:

  1. Перевірювані винятки
  2. Неперевірювані винятки

Перевірювані винятки

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

Цей тип винятків перевіряється під час компіляції: методи, які кидають перевірювані винятки, мають зазначити це у своїй сигнатурі, а код, що викликає метод, який може кинути перевірюваний виняток, зобовʼязаний його обробити, інакше код не скомпілюється.

Усі перевірювані винятки - це підкласи Exception, які не розширюють RuntimeException.

Неперевірювані винятки

Неперевірювані винятки - це виняткові умови, які застосунок зазвичай не може передбачити й не може з них відновитися. Приклад неперевірюваного винятку - NullPointerException, який виникає, коли метод, що має прийняти значення, відмінне від null, натомість отримує null.

Цей тип винятків не перевіряється під час компіляції: методи, які кидають неперевірювані винятки, не зобовʼязані зазначати це у своїй сигнатурі, а код, що викликає метод, який може кинути неперевірюваний виняток, не зобовʼязаний його обробляти.

Усі неперевірювані винятки успадковують RuntimeException, який, своєю чергою, розширює Exception.

Кидання винятків

Метод у Java може кинути виняток за допомогою інструкції throw.

Кидання перевірюваного винятку

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

public class InsufficientBalanceException extends Exception {

}

public class BankAccount {
  public void withdraw(double amount) throws InsufficientBalanceException {
    if (balance < amount) {
      throw new InsufficientBalanceException();
    }

    // rest of the method implementation
  }
}

Кидання неперевірюваного винятку

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

public class BankAccount {
  public void withdraw(double amount) {
    if (amount < 0) {
      throw new IllegalArgumentException("Cannot withdraw a negative amount");
    }

    // rest of the method implementation
  }
}

Обробка винятків

В Java винятки обробляють за допомогою ключових слів try, catch і finally.

  • Інструкції коду, які можуть кинути виняток, варто загорнути в блок try.
  • За блоком try іде один або кілька блоків catch, які перехоплюють винятки, кинуті в блоці try.
  • Після блоків catch може йти блок finally, який завжди виконується після блоку try, незалежно від того, чи було кинуто виняток.

У наступному прикладі показано, як працюють ці ключові слова:

public class ATM {
  public void withdraw(BankAccount bankAccount, double amount) {
    try {
      System.out.println("Withdrawing " + amount);
      bankAccount.withdraw(amount);
      System.out.println("Withdrawal succeeded");
    } catch (InsufficientBalanceException) {
      System.out.println("Withdrawal failed: insufficient balance");
    } catch (RuntimeException e) {
      System.out.println("Withdrawal failed: " + e.getMessage());
    } finally {
      System.out.println("Current balance: " + bankAccount.getBalance());
    }
  }
}

У цьому прикладі, коли винятку не кинуто, виводиться таке:

Withdrawing 10.0
Withdrawal succeeded
Current balance: 5.0

Якщо ж інструкція bankAccount.withdraw(amount) кине InsufficientBalanceException, виводиться таке:

Withdrawing 10.0
Withdrawal failed: insufficient balance
Current balance: 5.0

Або, якщо неперевірюваний виняток кине bankAccount.withdraw(amount), виводиться таке:

Withdrawing -10.0
Withdrawal failed: Cannot withdraw a negative amount
Current balance: 5.0

Помилки

У Java є також окрема категорія, яку називають помилками: це серйозні проблеми, зовнішні щодо застосунку. Приклад помилки - OutOfMemoryError, який виникає, коли застосунок намагається використати більше памʼяті, ніж є в системі.

Як і неперевірювані винятки, помилки не перевіряються під час компіляції. Різниця в тому, що вони означають проблеми на рівні системи, і зазвичай їх кидає віртуальна машина Java або середовище, а не застосунок. Застосунки зазвичай не повинні намагатися їх перехоплювати чи обробляти.

Усі помилки в Java успадковують клас Error.

Коли не варто використовувати винятки

Як уже зазначалося, винятки - це події, що порушують нормальний потік інструкцій, і призначені вони для обробки виняткових подій. Тому не рекомендується використовувати винятки для керування потоком виконання у своєму застосунку.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Винятки