Наследуется ли RuntimeException от Exception в Java?

Ответ

Да. RuntimeException является прямым подклассом Exception.

Иерархия исключений:

Throwable
├── Error (непроверяемые, например, OutOfMemoryError)
└── Exception
    ├── IOException, SQLException и др. (проверяемые исключения)
    └── RuntimeException (непроверяемые исключения)
        ├── NullPointerException
        ├── IllegalArgumentException
        └── ...

Ключевое отличие — проверяемость (checked vs unchecked):

  • Exception (кроме RuntimeException): Проверяемые (checked). Компилятор требует их обработки через try-catch или объявления в throws.
    // Проверяемое исключение - требует обработки
    public void readFile() throws IOException {
        // код, который может выбросить IOException
    }
  • RuntimeException и его наследники: Непроверяемые (unchecked). Обработка не обязательна.
    // Непроверяемое исключение - обработка не требуется
    public void calculate(String str) {
        int length = str.length(); // Может выбросить NullPointerException
    }

    Почему так? RuntimeException обозначает ошибки программиста (например, обращение к null, неверный аргумент), которые часто невозможно осмысленно обработать в коде.

Ответ 18+ 🔞

А, ну вот, классика жанра! Сейчас разберёмся, кто тут кому папа, а то народ путается, как в тёмной комнате.

Смотри, вся эта куча исключений — она как семья, блядь, большая и не очень дружная. На самом верху сидит дедушка Throwable. У него два сына: один — Error (это когда всё настолько пиздецово, что уже ничего не попишешь, типа OutOfMemoryError), а второй — Exception.

Вот этот второй сын, Exception, — он уже наш, рабоче-крестьянский. У него тоже куча отпрысков. И вот тут начинается самое интересное, ёпта. Одни его дети — это законопослушные граждане. IOException, SQLException. Проверяемые исключения (checked). Компилятор за ними, как сука-мамаша, следит: «А ты обработал? А ты в throws объявил? А то я компилировать не буду, пидорас!». И правда, не будет.

// Смотри, как оно: объявляешь, что может вылететь кирпич.
public void readFile() throws IOException {
    // Тут код, который может накосячить с файлом.
}

А есть другие дети — отбитые, неформалы. Это RuntimeException и вся его шайка: NullPointerException, IllegalArgumentException. Непроверяемые исключения (unchecked). Компилятор на них смотрит сквозь пальцы: «Ладно, летите, ебушки-воробушки. Разберётесь на месте». Обрабатывать их не заставляют.

// А тут — полная анархия. Можешь хоть на нулевой ссылке метод вызывать.
public void calculate(String str) {
    int length = str.length(); // Может вылететь NullPointerException, и всем похуй.
}

А почему так, спрашиваешь? Да потому что RuntimeException — это обычно не «ошибка системы», а косяк самого программиста. Нулевой указатель передал, индекс за границы массива полез, аргумент кривой подсунул. На что тут надеяться? На исправление в рантайме? Да в рот мне чих-пых! Чаще всего такой косяк не обработать — его надо в коде исправлять, а не try-catch'ем прикрывать. Вот и сделали их непроверяемыми, чтобы не засирать код лишними объявлениями.

Так что да, RuntimeException — это прям законный наследник Exception, просто с характером, блядь. Сынок, который пришёл на семейный ужин в рваных джинсах и всех послал.