Пользовательские исключения
Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 60 из 87.
Встроенные исключения Java охватывают многие распространённые сценарии ошибок, но иногда нужны исключения, специфичные для предметной области вашего приложения. Пользовательские исключения позволяют создавать осмысленные типы ошибок, которые ясно сообщают, что пошло не так.
Чтобы создать custom exception, просто расширьте существующий класс exception. Для checked exception расширьте Exception:
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}Для непроверяемого исключения расширьте RuntimeException:
public class InvalidAgeException extends RuntimeException {
public InvalidAgeException(String message) {
super(message);
}
}Вызов super(message) передаёт message об ошибке родительскому классу, делая его available через getMessage(). Затем вы можете выбросить и catch своё custom exception так же, как любое другое:
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException("Balance too low: " + balance);
}
balance -= amount;
}
// Использование
try {
account.withdraw(1000);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
}Пользовательские исключения делают ваш код более понятным и позволяют вызывающим сторонам по-разному обрабатывать определённые условия ошибок. Они особенно полезны при создании API или библиотек, где важно чётко сообщать об ошибках.
Задание
ЛегкоДавайте создадим систему бронирования билетов, которая использует custom исключения для обработки различных сценариев ошибок! Вы создадите понятные типы исключений, которые ясно сообщают, что пошло не так при бронировании билетов.
Вы организуете код в четырех файлах:
TicketSoldOutException.java: Create custom checked исключение (extendsException) для случаев, когда билеты больше недоступны. Ваше исключение должно принимать message в своем constructor и передавать его родительскому классу с помощьюsuper(message).InvalidSeatException.java: Create custom unchecked исключение (extendsRuntimeException) для случаев, когда кто-то пытается забронировать недействительный номер места. Это исключение также должно принимать и передавать message своему родительскому классу.TicketBooth.java: Create class, который manages продажу билетов. Ваша booth должна отслеживать общее number available мест и наибольший допустимый number места. Включите:Constructor, который принимает общее number available мест.
method
bookTicket(int seatNumber), который проверяет бронирование. Если билетов не осталось (available мест равно 0 или меньше), выбросьтеTicketSoldOutExceptionс message"No tickets remaining". Если number места меньше 1 или больше общего number мест, выбросьтеInvalidSeatExceptionс message"Seat [seatNumber] does not exist". Otherwise, уменьшите number available мест на 1 и выведитеBooked seat [seatNumber] successfully.method
getAvailableSeats(), который возвращает текущее count available мест.Main.java: Объедините вашу систему бронирования билетов! Вы получите два входных значения: общее number мест и number места для бронирования.Create
TicketBoothс given общим количеством мест. Затем попытайтесь забронировать указанный number места внутри блока try-catch. ПосколькуTicketSoldOutExceptionявляется checked, вы must обработать его. ПерехватитеTicketSoldOutExceptionfirst и выведитеBooking failed: [exception message]. Затем перехватитеInvalidSeatExceptionи выведите тот же формат:Booking failed: [exception message].After блока try-catch выведите
Remaining seats: [count], используя getter method.
Вы получите два входных значения по порядку: общее количество мест (целое число) и number места для бронирования (целое число).
Обратите внимание, как checked исключения заставляют вызывающий код обрабатывать их (с помощью try-catch или throws), тогда как unchecked исключения не требуют явной обработки. Выбирайте тип исключения в зависимости от того, является ли ошибка такой, которую вызывающие стороны должны предвидеть и обрабатывать!
Попробуйте сами
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int totalSeats = scanner.nextInt();
int seatNumber = scanner.nextInt();
// TODO: Создайте TicketBooth с заданным общим количеством мест
// TODO: Используйте блок try-catch для попытки забронировать место
// - Сначала перехватите TicketSoldOutException и выведите "Booking failed: [exception message]"
// - Перехватите InvalidSeatException и выведите "Booking failed: [exception message]"
// TODO: After the try-catch, print "Remaining seats: [count]"
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово thisМетодыПоля (атрибуты)Метод-конструкторПерегрузка конструкторовИтоги — Простой калькулятор4Наследование
Основы наследования (extends)Ключевое слово superПереопределение методов (@Override)Цепочка конструкторовКласс ObjectОдиночное и многоуровневое наследованиеПочему нет множественного наследования классовИтоги — Иерархия сотрудников7Специальные методы и класс Object
Метод toString()equals() и hashCode()Метод clone()compareTo() и ComparableИнтерфейс ComparatorПовторение — Кастомная сортировка10Обработка исключений в ООП
Иерархия классов исключенийПользовательские исключенияПроверяемые и непроверяемые ошибкиПаттерн Try With ResourcesПовторение — Validated User2Модификаторы доступа и инкапсуляция
Обзор уровней доступаМетоды геттеры и сеттерыСокрытие данныхКлючевое слово finalИтоги — Менеджер банковского счета5Полиморфизм
Основы перегрузки методовПереопределение методов (Run-Time)Upcasting и DowncastingОператор instanceofАбстрактные классы и методыИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияАгрегация против композицииВнутренние, вложенные и анонимные классыEnums и методы перечисленийRecords (Java 16+)Sealed-классы (Java 17+)11Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy3Свойства класса и статические члены
Переменные экземпляра и статические переменныеСтатические методыСтатические блокиКонстанты (static final)Итоги: Счетчик и утилиты6Интерфейсы и абстрактные классы
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовDefault и Static методы в интерфейсахАбстрактные классы vs ИнтерфейсыФункциональные интерфейсыИтоги — Платежная система9Обобщения
Введение в обобщенияОбобщенные классыОбобщенные методыОграниченные параметры типаСимволы подстановки (Wildcards: ?, extends, super)Итоги — Обобщенный контейнер12Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»Потренируйтесь самостоятельно: Онлайн-компилятор Java