Как создать своё исключение
Короткий ответ
Создайте класс, унаследованный от RuntimeException, и передайте сообщение в конструктор родителя:
class InsufficientFundsException extends RuntimeException {
InsufficientFundsException(String message) {
super(message);
}
}
void withdraw(int balance, int amount) {
if (amount > balance) {
throw new InsufficientFundsException("Need " + amount + ", have " + balance);
}
}
void main() {
try {
withdraw(100, 250);
} catch (InsufficientFundsException e) {
IO.println("Error: " + e.getMessage());
}
}Результат:
Error: Need 250, have 100Проверяемое или нет
Наследник RuntimeException — непроверяемое исключение: компилятор не требует его обрабатывать. Наследник Exception — проверяемое: метод обязан объявить его в throws, а вызывающий код — обработать:
class ConfigException extends Exception {
ConfigException(String message) {
super(message);
}
}
String readSetting(String key) throws ConfigException {
throw new ConfigException("Missing setting: " + key);
}
void main() {
try {
readSetting("db.url");
} catch (ConfigException e) {
IO.println(e.getMessage());
}
}Результат:
Missing setting: db.urlПричина
Если исключение возникло из-за другого, передайте исходное вторым аргументом — оно сохранится в getCause():
class ImportException extends RuntimeException {
ImportException(String message, Throwable cause) {
super(message, cause);
}
}
void main() {
try {
try {
Integer.parseInt("12x");
} catch (NumberFormatException e) {
throw new ImportException("Bad row 7", e);
}
} catch (ImportException e) {
IO.println(e.getMessage());
IO.println(e.getCause().getMessage());
}
}Результат:
Bad row 7
For input string: "12x"Дополнительные данные
В исключении можно хранить поля — например, код ошибки для ответа API:
class ApiException extends RuntimeException {
private final int status;
ApiException(int status, String message) {
super(message);
this.status = status;
}
int status() {
return status;
}
}
void main() {
try {
throw new ApiException(404, "Order not found");
} catch (ApiException e) {
IO.println(e.status() + " " + e.getMessage());
}
}Результат:
404 Order not foundЧастая ошибка
Унаследоваться от Exception, но не объявить исключение в throws. Компилятор отказывается собирать такой код:
class ConfigException extends Exception {
ConfigException(String message) {
super(message);
}
}
void load() {
throw new ConfigException("no file");
}
void main() {
load();
}Результат:
Main.java:8: error: unreported exception Main.ConfigException; must be caught or declared to be thrownФункции из этого ответа
- throw — Бросает исключение и прерывает выполнение метода.
- throws — Объявляет, какие проверяемые исключения может бросить метод.
- RuntimeException — Базовый класс непроверяемых исключений — ошибок в логике программы.
- Throwable.getMessage() — Возвращает текст сообщения исключения.