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

Какие знаешь RuntimeException в Java?

2.2 Middle🔥 191 комментариев
#Основы Java

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

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

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

RuntimeException в Java

RuntimeException — это unchecked exception, которые наследуют от класса RuntimeException. Они не требуют явной обработки (try-catch) и часто указывают на ошибки программиста.

Иерархия Exception в Java

Throwable
  ├── Error (серьёзные ошибки JVM)
  └── Exception
        ├── Checked Exception (требуют обработки)
        │   ├── IOException
        │   ├── SQLException
        │   └── ...
        └── RuntimeException (unchecked)
            ├── NullPointerException
            ├── ArrayIndexOutOfBoundsException
            ├── IllegalArgumentException
            └── ...

Основные RuntimeException

1. NullPointerException (NPE)

Одна из самых частых ошибок:

public class NullPointerExceptionExample {
    public void process(String data) {
        // Ошибка: data может быть null
        int length = data.length();  // NPE!
    }
    
    // Правильно: проверяй на null
    public void processChecked(String data) {
        if (data != null) {
            int length = data.length();
        }
    }
    
    // Или используй Optional
    public void processOptional(String data) {
        Optional.ofNullable(data)
            .ifPresent(d -> System.out.println(d.length()));
    }
}

2. ArrayIndexOutOfBoundsException

Попытка доступа к элементу вне границ массива:

public class ArrayIndexException {
    public void process() {
        int[] numbers = {1, 2, 3};
        // Ошибка: индекс 5 не существует (макс 2)
        int value = numbers[5];  // ArrayIndexOutOfBoundsException!
    }
    
    // Правильно
    public void processCorrect() {
        int[] numbers = {1, 2, 3};
        if (5 < numbers.length) {
            int value = numbers[5];
        }
    }
}

3. ClassCastException

Ошибка при неправильном приведении типа:

public class ClassCastExceptionExample {
    public void process(Object obj) {
        // Опасно: может быть не String
        String str = (String) obj;  // ClassCastException!
    }
    
    // Правильно: проверяй instanceof
    public void processChecked(Object obj) {
        if (obj instanceof String) {
            String str = (String) obj;
        }
    }
    
    // Java 16+: Pattern Matching
    public void processPattern(Object obj) {
        if (obj instanceof String str) {
            System.out.println(str.length());
        }
    }
}

4. IllegalArgumentException

Передан неверный аргумент методу:

public class IllegalArgumentExceptionExample {
    @Service
    public class UserService {
        public User createUser(String name, int age) {
            // Валидация
            if (name == null || name.isEmpty()) {
                throw new IllegalArgumentException(
                    "Name cannot be empty"
                );
            }
            if (age < 0 || age > 150) {
                throw new IllegalArgumentException(
                    "Invalid age: " + age
                );
            }
            return new User(name, age);
        }
    }
}

5. IllegalStateException

Объект находится в неверном состоянии для выполнения операции:

public class StatefulService {
    private boolean initialized = false;
    
    public void execute() {
        if (!initialized) {
            throw new IllegalStateException(
                "Service not initialized. Call init() first."
            );
        }
        // Выполнить операцию
    }
    
    public void init() {
        initialized = true;
    }
}

6. UnsupportedOperationException

Операция не поддерживается:

public class UnmodifiableListExample {
    public void process() {
        List<String> immutableList = 
            Collections.unmodifiableList(
                Arrays.asList("a", "b", "c")
            );
        
        // Ошибка: нельзя модифицировать
        immutableList.add("d");  // UnsupportedOperationException!
    }
}

7. NumberFormatException

Ошибка при парсинге строки в число:

public class NumberFormatExceptionExample {
    public void process() {
        String value = "abc";
        // Ошибка: "abc" не число
        int number = Integer.parseInt(value);  // NumberFormatException!
    }
    
    // Правильно: обработай исключение
    public void processChecked() {
        String value = "abc";
        try {
            int number = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            System.err.println("Invalid number format: " + value);
        }
    }
}

8. ConcurrentModificationException

Модификация коллекции во время итерации:

public class ConcurrentModificationExample {
    public void badApproach() {
        List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
        // Ошибка: модифицируем во время итерации
        for (String item : list) {
            if (item.equals("b")) {
                list.remove(item);  // ConcurrentModificationException!
            }
        }
    }
    
    // Правильно
    public void correctApproach() {
        List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
        list.removeIf(item -> item.equals("b"));
    }
}

9. ArithmeticException

Математическая ошибка (например, деление на ноль):

public class ArithmeticExceptionExample {
    public void divide(int a, int b) {
        // Ошибка: деление на ноль
        int result = a / b;  // ArithmeticException!
    }
    
    // Правильно
    public void divideChecked(int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException(
                "Divisor cannot be zero"
            );
        }
        int result = a / b;
    }
}

10. NoSuchElementException

Попытка получить элемент, который не существует:

public class NoSuchElementExample {
    public void process() {
        Optional<String> optional = Optional.empty();
        // Ошибка: элемента нет
        String value = optional.get();  // NoSuchElementException!
    }
    
    // Правильно
    public void processChecked() {
        Optional<String> optional = Optional.empty();
        String value = optional.orElse("default");
    }
}

Таблица основных RuntimeException

ExceptionПричинаПример
NullPointerExceptionNull ссылкаobj.method() при obj == null
ArrayIndexOutOfBoundsExceptionИндекс вне границarr[10] при length = 5
ClassCastExceptionНеправильное приведение типа(String) integerObj
IllegalArgumentExceptionНеверный аргументnegative age
IllegalStateExceptionНеверное состояние объектаuse before init()
UnsupportedOperationExceptionОперация не поддерживаетсяadd() на unmodifiable list
NumberFormatExceptionОшибка парсинга числаInteger.parseInt("abc")
ConcurrentModificationExceptionМодификация во время итерацииlist.remove() в for-each
ArithmeticExceptionМатематическая ошибкаa / 0
NoSuchElementExceptionЭлемент не найденlist.get(999)

Лучшие практики

// 1. Не ловите RuntimeException без причины
// Плохо:
try {
    doSomething();
} catch (RuntimeException e) {
    // Скрывает ошибки
}

// Хорошо:
try {
    int value = Integer.parseInt(userInput);
} catch (NumberFormatException e) {
    logger.error("Invalid number: {}", userInput, e);
}

// 2. Создавайте собственные RuntimeException для специфичных ошибок
public class BusinessLogicException extends RuntimeException {
    public BusinessLogicException(String message) {
        super(message);
    }
    
    public BusinessLogicException(String message, Throwable cause) {
        super(message, cause);
    }
}

// 3. Используй fail-fast: валидируй рано
public void processUser(User user) {
    if (user == null) {
        throw new IllegalArgumentException("User cannot be null");
    }
    // Продолжай работу
}

Вывод

RuntimeException — это мощный инструмент для обработки ошибок, которые нельзя предусмотреть на этапе компиляции. Используй их правильно: валидируй входные данные, проверяй граничные условия, избегай null ссылок. Помни, что unchecked исключения — это всё равно исключительные ситуации и их нужно обрабатывать осознанно.