Автор: Widowmaker1984

Вопросы 101-106, 109-113, 117-119 (обработка исключений)

"Какие существуют способы обработки исключений?"
"О чем говорит ключевое слово throws?"
"В чем особенность блока finally? Всегда ли он исполняется?"
скрытый текст"Может ли не быть ни одного блока catch при отлавливании исключений?"
"Могли бы вы придумать ситуацию, когда блок finally не будет выполнен?"
"Может ли один блок catch отлавливать несколько исключений (с одной и разных веток наследований)?"
"Как написать собственное («пользовательское») исключение? Какими мотивами вы будете руководствоваться при выборе типа исключения: checked/unchecked?"
"Какой оператор позволяет принудительно выбросить исключение?"
"Есть ли дополнительные условия к методу, который потенциально может выбросить исключение?"
"Может ли метод main выбросить исключение вовне и если да, то где будет происходить обработка данного исключения?"
"Если оператор return содержится и в блоке catch и в finally, какой из них «главнее»?"
"Какая конструкция используется в Java для обработки исключений?"
"Возможно ли использование блока try-finally (без catch)?"

"Предположим, есть блок try-finally. В блоке try возникло исключение и выполнение переместилось в блок finally. В блоке finally тоже возникло исключение. Какое из двух исключений “выпадет” из блока try-finally? Что случится со вторым исключением?"


1. В Java есть пять ключевых слов для работы с исключениями:
try - данное ключевое слово используется для отметки начала блока кода, который потенциально может привести к ошибке.
catch - ключевое слово для отметки начала блока кода, предназначенного для перехвата и обработки исключений.
finally - ключевое слово для отметки начала блока кода, которое является дополнительным. Этот блок помещается после последнего блока 'catch'. Управление обычно передаётся в блок 'finally' в любом случае.
throw - служит для генерации исключений.
throws - ключевое слово, которое прописывается в сигнатуре метода, и обозначающее что метод потенциально может выбросить исключение с указанным типом.

скрытый текст2. Когда возникает исключительное состояние, создается объект одного из подклассов Exception. По его типу становится яснее, какая именно ошибка возникла при выполнении программы. Созданный объект пересылается в метод, обрабатывающий данный тип исключительной ситуации.

2.1. Для задания блока программного кода, который требуется защитить от исключений, используется ключевое слово try. Сразу же после try-блока помещается блок catch, задающий тип исключения которое вы хотите обрабатывать. Целью большинства хорошо сконструированных catch-разделов должна быть обработка возникшей исключительной ситуации и приведение переменных программы в некоторое разумное состояние — такое, чтобы программу можно было продолжить так, будто никакой ошибки и не было.

2.1.1. Общий вид конструкции для «поимки» исключительной ситуации выглядит следующим образом:

try{
//здесь код, который потенциально может привести к ошибке
}
catch(SomeException e ){ //в скобках указывается класс конкретной ожидаемой ошибки
//здесь описываются действия, направленные на обработку исключений
}
finally{
//выполняется в любом случае ( блок finally не обязателен)
}

скрытый текст2.2. В некоторых случаях один и тот же блок программного кода может возбуждать исключения различных типов. Для того, чтобы обрабатывать подобные ситуации, Java позволяет использовать для одного try-блока любое количество catch-разделов. Наиболее специализированные классы исключений должны идти первыми, поскольку ни один подкласс не будет достигнут, если поставить его после суперкласса.

2.3. Операторы try можно вкладывать друг в друга аналогично тому, как можно создавать вложенные области видимости переменных. Если у оператора try низкого уровня нет раздела catch, соответствующего возбужденному исключению, стек будет развернут на одну ступень выше, и в поисках подходящего обработчика будут проверены разделы catch внешнего оператора try.

2.4. В Java 7 стала доступна новая конструкция, с помощью которой можно перехватывать несколько исключений одним блоком catch. Пример:

catch( IOException | SQLException ex )

2.5. Конструкция try-with-resources, также именуемая "автоматическое управление ресурсами", представляет новый механизм обработки исключений, который был представлен в Java 7 , осуществляя автоматическое закрытие всех ресурсов, используемых в рамках блока try/catch.

2.5.1. Чтобы воспользоваться данным оператором, нужно разместить заданные ресурсы в круглых скобках, после чего созданный ресурс будет автоматически закрыт по окончании блока.

2.5.2. При работе с конструкцией try-with-resources следует принимать во внимание следующие нюансы:
- С целью использования конструкции try-with-resources следует реализовать интерфейс AutoCloseable, после чего соответствующий метод close() будет вызван автоматически во время выполнения.
- В конструкции try-with-resources возможно указание одного и более классов.
- При указании нескольких классов в блоке try конструкции try-with-resources, закрытие данных классов будет производиться в обратном порядке.
- За исключением внесения ресурсов в скобки, прочие элементы аналогичны нормальному блоку try/catch в составе блока try.

3. Исключения могут возбуждаться и «вруч­ную» для того, чтобы сообщить о некоторых нештатных ситуациях.

3.1. Оператор throw используется для возбуждения исключения «вруч­ную». Для того, чтобы сделать это, нужно иметь объект подкласса клас­са Throwable, который можно либо получить как параметр оператора catch, либо создать с помощью оператора new. Ниже приведена общая форма оператора throw:

throw [ОбъектТипаThrowable];

3.1.1. При достижении этого оператора нормальное выполнение кода немедленно прекращается, так что следующий за ним оператор не выполняется. Ближайший окружающий блок try проверяется на наличие соответствующего возбужденному исключению обработчика catch. Если такой отыщется, управление передается ему. Если нет, проверяется следующий из вложенных операторов try, и так до тех пор пока либо не будет найден подходящий раздел catch, либо обработчик исключений исполняющий системы Java не остановит программу, выведя при этом состояние стека вызовов.

3.2. Только подклассы класса Throwable могут быть возбуждены или перехвачены. Простые типы (int, char и т.п.), а также классы, не являющиеся подклассами Throwable (например, String и Object) использоваться в качестве исключений не могут. Наиболее общий путь для использования исключений — создание своих собственных подклассов класса Ex­ception.

3.2.1. При создании собственных классов исключений следует принимать во внимание следующие аспекты:
- Все исключения должны быть дочерними элементами Throwable.
- Если планируете создать контролируемое исключение, следует расширить класс Exception.
- Если хотите создать исключение на этапе выполнения, следует расширить класс RuntimeException.

4. Обработка исключения может быть произведена с помощью операторов try…catch, либо "проброшена" внешней части программы. Т.е. метод может передавать возникшие в нём исключения выше по иерархии вызовов, сам его не обрабатывая. Если исключение обрабатывается в методе, оно не обязано "пробрасываться", и наоборот.

4.1. Если метод способен возбуждать исключения, которые он сам не обрабатывает, он должен объявить о таком поведении, чтобы вызывающие методы могли защитить себя от этих исключений. Для задания списка исключений, которые могут возбуждаться методом, используется ключевое слово throws. Если метод в явном виде (т.е. с помощью оператора throw) возбуждает исключение соответствующего класса, тип класса исключений должен быть указан в операторе throws в объявлении этого метода.

4.2. С учетом этого наш прежний синтаксис определения метода должен быть расширен следующим образом:
тип имя_метода(список аргументов) throws список_исключений

4.2. Метод может "пробрасывать" исключения, которые в нем реально не падают (например, на будущее) или пробрасывать исключения более "широких" классов, чем в нем возможны.

4.4. Метод public static void main( String[] args ) - обычный метод, и кроме того, что вызывается виртуальной машиной для начала выполнения программы, может быть вызван из любого другого кода. На него распространяются обычные правила указания выбрасываемых проверяемых исключений (checked exceptions) после throws.

4.4.1. Поэтому если код в main может вызвать проверяемые исключения (например, вы читаете файл с помощью Files.lines() который может бросить IOException), компилятор заставит вас либо поймать исключение в try-catch, либо указать его в throws.

4.4.1.1. Не пойманные исключения ловит экземпляр java.lang.Thread.UncaughtExceptionHandler. У каждого Thread может быть свой обработчик (задается через setUncaughtExceptionHandler; обрабатывает исключения, брошенные в этом процессе), либо можно установить обработчик по-умолчанию, через Thread.setDefaultUncaughtExceptionHandler, который и будет обрабатывать все необработанные исключения.

5. Иногда требуется гарантировать, что определенный участок кода будет выполняться независимо от того, какие исключения были возбуждены и перехвачены. Для создания такого участка кода используется ключевое слово finally. Он очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для временного использования в начале выполнения метода.

5.1. Даже в случаях, когда в методе нет соответствующего возбужденному исключению раздела catch, блок finally будет выполнен до того, как управление перейдет к операторам, следующим за разделом try.

5.2. Следует помнить, что:
- Выражение catch не может существовать без оператора try.
- При наличии блока try/catch, выражение finally не является обязательным.
- Блок try не может существовать при отсутствии выражения catch либо выражения finally.
- Существование какого-либо кода в промежутке между блоками try, catch, finally является невозможным.

5.2.1. Запись без catch допустима, если имеется связка try... finally . Но смысла в подобной записи немного.

5.3. Блок finally выполняется не всегда, например если в блоке try вызывать System.exit(0), то finally недостижим, так как происходит системный выход из программы. Общими словами: когда JVM умирает, ей уже не до finally.

5.4. Если в блоке try есть return, блок finally все равно будет вызван. А если данный блок содержит уже свой return, то именно он в итоге и будет задавать возвращаемое значение. В этом смысле данный return "главнее".

5.5. Аналогично, если в обоих блоках упадут исключения, то исключение в finally «проглотит» исключение в try. Чтобы не "потерять" исключение, его можно обработать в блоке try.
1

Комментарии


Лучшее   Правила сайта   Вход   Регистрация   Восстановление пароля

Материалы сайта предназначены для лиц старше 16 лет (16+)