Треки
/
Java
Java
/
Вправи
/
Загадка калькулятора
Загадка калькулятора

Загадка калькулятора

Навчальна вправа

Вступ

Винятки

Мова програмування 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.

Вказівки

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

Мета - мати робочий калькулятор, який повертає рядок тексту (англ. string) такого вигляду: 16 + 51 = 67, коли йому передати аргументи 16, 51 і +.

CalculatorConundrum calculator = new CalculatorConundrum();

calculator.calculate(16, 51, "+");
// => returns "16 + 51 = 67"

calculator.calculate(32, 6, "*");
// => returns "32 * 6 = 192"

calculator.calculate(512, 4, "/");
// => returns "512 / 4 = 128"

1. Реалізуйте метод calculate, щоб підтримувати кілька базових операцій

Головний метод, який потрібно реалізувати в цьому завданні, - метод CalculatorConundrum.calculate(). Він приймає три аргументи. Перші два аргументи operand1 і operand2 - цілі числа, над якими виконуватиметься операція. Третій аргумент operation має тип рядок тексту, і в цій вправі потрібно реалізувати такі операції:

  • додавання за допомогою рядка тексту +
  • множення за допомогою рядка тексту *
  • ділення за допомогою рядка тексту /

2. Опрацюйте недопустимі операції

Оновіть метод CalculatorConundrum.calculate(), щоб він опрацьовував недопустимі операції:

  • Коли аргумент operation дорівнює null, потрібно викинути IllegalArgumentException з повідомленням Operation cannot be null.
  • Коли аргумент operation дорівнює "", потрібно викинути IllegalArgumentException з повідомленням Operation cannot be empty.
  • Коли аргумент operation є будь-якою операцією, крім +, * або /, потрібно викинути IllegalOperationException з повідомленням Operation '{operation}' does not exist.
calculator.calculate(10, 1, null);
// => throws IllegalArgumentException with message "Operation cannot be null"

calculator.calculate(10, 1, "");
// => throws IllegalArgumentException with message "Operation cannot be empty"

calculator.calculate(10, 1, "-");
// => throws IllegalOperationException with message "Operation '-' does not exist"

3. Опрацюйте виняток, що виникає при діленні на нуль

У Java спроба поділити на нуль викидає ArithmeticException. Оновіть метод CalculatorConundrum.calculate(), щоб він перехоплював цей виняток, а потім викидав IllegalOperationException з повідомленням Division by zero is not allowed, вказавши перехоплений ArithmeticException як причину.

calculator.calculate(512, 0, "/");
// => throws IllegalOperationException with message "Division by zero is not allowed"
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Java Exercism

Час розпочати Загадка калькулятора?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Java, а також 26 концепцій158 вправ та справжнє наставництво від людей, і все це безкоштовно.