← Назад к вопросам

Что такое Unchecked исключение?

1.0 Junior🔥 211 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Что такое Unchecked исключение?

Определение

Unchecked Exception (непроверяемое исключение) — это исключение, которое не проверяется компилятором. Программист не обязан его обрабатывать или объявлять в сигнатуре метода, хотя это рекомендуется.

Все Unchecked Exception наследуются от RuntimeException:

java.lang.RuntimeException
├── NullPointerException
├── ArrayIndexOutOfBoundsException
├── ArithmeticException
├── IllegalArgumentException
├── ClassCastException
├── NumberFormatException
└── ... (много других)

Ключевые отличия от Checked Exception

ОсобенностьUncheckedChecked
Наследуется отRuntimeExceptionException
Проверка компиляторомНЕТДА
Обязателен try-catchНЕТДА
Обязателен throwsНЕТДА
Возникает в runtimeОбычноПо необходимости
ПримерыNPE, AIOOBIOException, 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

✓ Используй для:

  1. Программных ошибок — ошибок, которые можно избежать валидацией
public void setQuantity(int qty) {
    if (qty < 0) {
        throw new IllegalArgumentException("Quantity cannot be negative");
    }
}
  1. Ошибок типа — когда тип не соответствует
if (!(obj instanceof String)) {
    throw new IllegalArgumentException("Expected String");
}
  1. Операций, которые обычно не должны возникать
public String divide(int a, int b) {
    // Дивизию на ноль мог проверить вызывающий код
    return String.valueOf(a / b);
}

✗ Не используй для:

  1. Внешних ошибок, которые должны быть обработаны
// Плохо
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");
}
  1. Восстанавливаемых ошибок
// Плохо
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

  1. Не глушите исключения
// Плохо
try {
    risky();
} catch (Exception e) {
    // Молчим
}

// Хорошо
try {
    risky();
} catch (NullPointerException e) {
    logger.error("NPE occurred", e);
    throw new RuntimeException("Failed to process", e);
}
  1. Ловите специфичные исключения
// Плохо
try {
    operation();
} catch (Exception e) { }

// Хорошо
try {
    operation();
} catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
    logger.error("Invalid access", e);
}
  1. Валидируйте входные данные вместо полагания на исключения
// Плохо - полагаемся на исключение
String result = array[i].toUpperCase();

// Хорошо - проверяем
if (i >= 0 && i < array.length && array[i] != null) {
    String result = array[i].toUpperCase();
}