Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Что такое Unchecked исключение?
Определение
Unchecked Exception (непроверяемое исключение) — это исключение, которое не проверяется компилятором. Программист не обязан его обрабатывать или объявлять в сигнатуре метода, хотя это рекомендуется.
Все Unchecked Exception наследуются от RuntimeException:
java.lang.RuntimeException
├── NullPointerException
├── ArrayIndexOutOfBoundsException
├── ArithmeticException
├── IllegalArgumentException
├── ClassCastException
├── NumberFormatException
└── ... (много других)
Ключевые отличия от Checked Exception
| Особенность | Unchecked | Checked |
|---|---|---|
| Наследуется от | RuntimeException | Exception |
| Проверка компилятором | НЕТ | ДА |
| Обязателен try-catch | НЕТ | ДА |
| Обязателен throws | НЕТ | ДА |
| Возникает в runtime | Обычно | По необходимости |
| Примеры | NPE, AIOOB | IOException, SQLException |
Примеры Unchecked Exception
1. NullPointerException (самое частое)
public class NullPointerExample {
public static void main(String[] args) {
String str = null;
// Никаких предупреждений от компилятора
System.out.println(str.length()); // Выбросит NullPointerException
}
}
// Можно обработать, но не обязательно
public class HandleNPE {
public static void main(String[] args) {
String str = null;
try {
System.out.println(str.length());
} catch (NullPointerException e) {
System.out.println("String is null");
}
}
}
2. ArrayIndexOutOfBoundsException
public class ArrayBoundsExample {
public static void main(String[] args) {
int[] array = {1, 2, 3};
// Компилятор не требует обработку
System.out.println(array[10]); // Выбросит ArrayIndexOutOfBoundsException
}
}
3. ArithmeticException
public class ArithmeticExample {
public static void main(String[] args) {
int result = 10 / 0; // Выбросит ArithmeticException
}
}
4. IllegalArgumentException
public class IllegalArgumentExample {
public static void setAge(int age) {
if (age < 0 || age > 120) {
// Можем выбросить unchecked exception
throw new IllegalArgumentException("Age must be between 0 and 120");
}
}
public static void main(String[] args) {
// Компилятор не требует обработку
setAge(-5); // Выбросит IllegalArgumentException
}
}
5. ClassCastException
public class ClassCastExample {
public static void main(String[] args) {
Object obj = "Hello";
// Компилятор не требует обработку
Integer num = (Integer) obj; // Выбросит ClassCastException
}
}
6. NumberFormatException
public class NumberFormatExample {
public static void main(String[] args) {
String str = "abc123";
// Компилятор не требует обработку
int num = Integer.parseInt(str); // Выбросит NumberFormatException
}
}
Различие между Checked и Unchecked
Checked Exception (обязателен try-catch)
import java.io.FileReader;
import java.io.IOException;
public class CheckedExceptionExample {
public static void main(String[] args) {
// ОШИБКА КОМПИЛЯТОРА! Нужен try-catch
FileReader reader = new FileReader("file.txt");
}
// Правильный вариант 1: try-catch
public static void readFile1() {
try {
FileReader reader = new FileReader("file.txt");
} catch (IOException e) {
System.err.println("Cannot read file: " + e.getMessage());
}
}
// Правильный вариант 2: throws
public static void readFile2() throws IOException {
FileReader reader = new FileReader("file.txt");
}
}
Unchecked Exception (опционален try-catch)
public class UncheckedExceptionExample {
// Компилятор не требует try-catch
public static void main(String[] args) {
String str = null;
System.out.println(str.length()); // Может выбросить NPE
}
// Но можем обработать, если хотим
public static void safeMain() {
try {
String str = null;
System.out.println(str.length());
} catch (NullPointerException e) {
System.err.println("String is null");
}
}
// Или декларировать, если хотим
public static void declaration() throws NullPointerException {
String str = null;
System.out.println(str.length());
}
}
Создание собственного Unchecked Exception
// Наследуемся от RuntimeException
public class InvalidUserInputException extends RuntimeException {
public InvalidUserInputException(String message) {
super(message);
}
public InvalidUserInputException(String message, Throwable cause) {
super(message, cause);
}
}
public class UserService {
// Не нужен throws в сигнатуре
public void validateEmail(String email) {
if (!email.contains("@")) {
throw new InvalidUserInputException("Invalid email format");
}
}
public static void main(String[] args) {
// Не требует try-catch
UserService service = new UserService();
service.validateEmail("invalid-email"); // Выбросит исключение
}
}
Когда использовать Unchecked Exception
✓ Используй для:
- Программных ошибок — ошибок, которые можно избежать валидацией
public void setQuantity(int qty) {
if (qty < 0) {
throw new IllegalArgumentException("Quantity cannot be negative");
}
}
- Ошибок типа — когда тип не соответствует
if (!(obj instanceof String)) {
throw new IllegalArgumentException("Expected String");
}
- Операций, которые обычно не должны возникать
public String divide(int a, int b) {
// Дивизию на ноль мог проверить вызывающий код
return String.valueOf(a / b);
}
✗ Не используй для:
- Внешних ошибок, которые должны быть обработаны
// Плохо
public void readFile(String filename) {
throw new RuntimeException(new IOException("File not found"));
}
// Хорошо
public void readFile(String filename) throws IOException {
throw new IOException("File not found");
}
- Восстанавливаемых ошибок
// Плохо
throw new RuntimeException("Connection timeout");
// Хорошо
throw new ConnectionTimeoutException("Connection timeout");
Обработка Unchecked Exception
public class ExceptionHandling {
public static void main(String[] args) {
// Вариант 1: Обработать
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.err.println("Error: " + e.getMessage());
}
// Вариант 2: Позволить упасть (обычно для развития)
int result = 10 / 0; // Выбросит исключение
// Вариант 3: Проверить условие вместо обработки
int denominator = 0;
if (denominator != 0) {
int result2 = 10 / denominator;
} else {
System.out.println("Cannot divide by zero");
}
}
}
Best Practices
- Не глушите исключения
// Плохо
try {
risky();
} catch (Exception e) {
// Молчим
}
// Хорошо
try {
risky();
} catch (NullPointerException e) {
logger.error("NPE occurred", e);
throw new RuntimeException("Failed to process", e);
}
- Ловите специфичные исключения
// Плохо
try {
operation();
} catch (Exception e) { }
// Хорошо
try {
operation();
} catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
logger.error("Invalid access", e);
}
- Валидируйте входные данные вместо полагания на исключения
// Плохо - полагаемся на исключение
String result = array[i].toUpperCase();
// Хорошо - проверяем
if (i >= 0 && i < array.length && array[i] != null) {
String result = array[i].toUpperCase();
}