Короткий ответ
Неперехваченное исключение всплывает вверх по стеку вызовов: текущий метод немедленно завершается, и исключение передаётся методу, который его вызвал, — процесс повторяется, пока не найдётся подходящий catch или исключение не достигнет main. По пути на каждом уровне выполняются блоки finally, а при отсутствии обработчика JVM завершает поток и печатает stack trace.
Как это работает подробнее
Распространение (exception propagation) начинается с места выброса исключения: текущий метод завершается, и исключение передаётся вызвавшему методу. Если подходящего catch нет, процесс идёт выше — по всему стеку вплоть до main. При прохождении каждого уровня выполняются все блоки finally, даже если исключение на этом уровне не перехватывается.
Когда catch найден, выполнение продолжается после этого блока. Для checked-исключений распространение «узаконено» объявлением throws в сигнатурах методов на пути; unchecked-исключения (RuntimeException и Error) проходят через любые методы без объявлений.
- Блоки
catchрасполагайте от конкретного исключения к более общему. - Необработанное исключение, дошедшее до
main, аварийно завершает поток: JVM печатает stack trace со всей цепочкой вызовов.
Пример кода
public class PropagationDemo {
static void a() {
b();
}
static void b() {
try {
c();
} finally {
System.out.println("finally в b()");
}
}
static void c() {
throw new RuntimeException("сбой в c()");
}
public static void main(String[] args) {
try {
a();
} catch (RuntimeException e) {
System.out.println("Поймано в main: " + e.getMessage());
e.printStackTrace();
}
}
}Что использовать на практике
- Ловите исключение там, где можете на него осмысленно отреагировать, а не на каждом уровне стека.
- Если метод не может обработать checked-исключение — честно объявите
throws, а не глотайте ошибку. - При логировании передавайте исключение целиком — stack trace важнее одного сообщения.
Подводные камни
- Пустой
catch«проглатывает» исключение и скрывает место сбоя. - Более общий
catchраньше конкретного делает блок недостижимым или неверным — порядок важен. - Unchecked-исключение может пройти через методы, которые его не объявляли, — ищите причину по stack trace, а не по сигнатурам.
Как отвечать на собеседовании
- Каркас: объясните механизм — исключение всплывает по стеку вызовов до первого подходящего
catch→ добавьте, чтоfinallyвыполняется на каждом уровне → упомяните требованиеthrowsдля checked → завершите сценарием «не поймано до main — JVM печатает stack trace».