throw и throws в Java: разница и примеры - Вопросы

Всего: 5 вопросов

1. 

Чем throw отличается от throws в Java?

throw — исполняемая инструкция в теле метода: она выбрасывает один конкретный объект исключения и прерывает выполнение, например throw new IOException("Файл не найден"). throws — часть объявления метода или конструктора после списка параметров: она ничего не выбрасывает, а перечисляет через запятую типы исключений, которые метод может передать вызывающему коду, например void read() throws IOException, ParseException. Обычно они работают в паре: throw внутри метода, throws в его заголовке.

2. 

Когда throws в сигнатуре метода обязателен, а когда можно использовать throw без throws?

throws обязателен, если метод может выбросить проверяемое (checked) исключение и не перехватывает его сам. Иначе компилятор выдаст error: unreported exception IllegalAccessException; must be caught or declared to be thrown. Без throws можно обойтись, если выбрасывается RuntimeException, Error или их подкласс, либо если checked-исключение перехватывается блоком catch в том же методе. Вызывающий метод, в свою очередь, обязан перехватить объявленное checked-исключение или сам указать его в throws. При этом throws не обрабатывает исключение, а только перекладывает ответственность на вызывающий код.

3. 

Как повторно выбросить перехваченное исключение и что такое точный повторный выброс в Java 7+?

Внутри блока catch пишут throw e; — выбрасывается тот же объект с исходным сообщением и стеком вызовов. Так делают, когда метод должен отреагировать на ошибку (записать в лог), но обработку оставить вызывающему коду. Чтобы сменить тип, создают новое исключение и передают исходное как причину: throw new IllegalStateException("Не удалось загрузить заказ", e). С Java 7 работает точный повторный выброс: после catch (Exception e) { throw e; } метод может объявить в throws только те checked-исключения, которые реально выбрасывает блок try (например, throws IOException, а не throws Exception). Условие — параметр e не переприсваивается в catch.

4. 

Как объявить несколько исключений в throws и как их должен обработать вызывающий код?

Типы перечисляют через запятую в любом порядке: static void load(int mode) throws IOException, ParseException. Вызывающий код должен обработать каждое проверяемое исключение из списка — отдельными блоками catch, одним multi-catch catch (IOException | ParseException e) или общим суперклассом; если пропустить хотя бы одно, будет ошибка компиляции. throws Exception покрывает все checked-исключения сразу, но скрывает, что именно может пойти не так, поэтому лучше указывать конкретные типы. Подкласс вместе с суперклассом (throws FileNotFoundException, IOException) допустим, хотя избыточен.

5. 

Что можно указать после throw и что произойдёт при throw null?

После throw допускается только выражение типа Throwable или его подкласса: новый объект (throw new IllegalArgumentException("...")) или параметр блока catch. throw "Ошибка"; и throw 42; не компилируются: incompatible types: String cannot be converted to Throwable. throw null; или ссылка подходящего типа, равная null, компилируется, но при выполнении вместо задуманного исключения выбрасывается NullPointerException. Кроме того, throw всегда завершает текущий блок: инструкция сразу после него вызывает ошибку unreachable statement, а метод с возвращаемым значением может заканчиваться на throw без return.

Страница 1 из 1