Короткий ответ
throw — оператор, который в точке выполнения кода непосредственно выбрасывает исключение: после него указывается объект-исключение, например throw new IllegalArgumentException(). throws — объявление в сигнатуре метода о том, какие исключения метод может выбросить: void read() throws IOException. Первый пишется в теле метода, второй — в его сигнатуре.
Как это работает подробнее
throw используется внутри тела метода. Бросить можно только объект класса, наследующего Throwable. Один вызов throw бросает ровно одно исключение, после чего управление уходит на поиск подходящего catch или выше по стеку.
throws стоит в сигнатуре и сообщает компилятору и вызывающему коду, что метод может выбросить перечисленные исключения. Если метод способен выбросить checked-исключение, он обязан либо перехватить его в try-catch, либо объявить в throws — иначе код не скомпилируется. Для unchecked-исключений (RuntimeException и Error) объявление не обязательно.
- throw работает с объектом исключения и пишется в теле метода.
- throws работает с типами исключений и пишется в сигнатуре метода.
Пример кода
import java.io.IOException;
public class ThrowVsThrows {
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Возраст не может быть отрицательным");
}
}
public void load() throws IOException, InterruptedException {
// метод может выбросить оба checked-исключения
}
}Что использовать на практике
throwиспользуйте, чтобы сигнализировать об ошибке прямо в коде: например,IllegalArgumentExceptionпри невалидных аргументах.throwsобъявляйте для checked-исключений, которые метод может выбросить и не обрабатывает сам.- Unchecked-исключения в
throwsне перечисляйте — обязательности нет, пользы никакой.
Подводные камни
- Их легко перепутать: после
throwидёт объект исключения, послеthrows— классы исключений через запятую. - Checked-исключение без
try-catchи безthrowsв сигнатуре — ошибка компиляции. throwsсRuntimeExceptionизбыточен: он ничего не гарантирует вызывающему коду.
Как отвечать на собеседовании
- Каркас: разведите роли —
throwреально выбрасывает исключение,throwsобъявляет его в сигнатуре → уточните, где что пишется: тело метода vs сигнатура → свяжите с правилом checked: обработай или объяви → приведите мини-пример.