Что такое ошибка а что такое исключительная ситуация java

BestProg

Содержание

Поиск на других ресурсах:

1. Что такое исключительная ситуация?

Исключительная ситуация – это программная ошибка, которая возникает во время выполнения последовательности программного кода. Программная ошибка может быть логической ошибкой программиста во время разработки программы. Например, исключительная ситуация может возникать в случаях:

Правильная обработка исключений есть важным элементом написания профессиональных программ на Java.

2. Понятие исключения в языке Java

Как правило, каждая исключительная ситуация может иметь свой код ошибки и обработку этого кода (вывод соответствующих сообщений, и т.п.). В языке программирования Java разработан механизм обработки исключительных ситуаций.

В языке программирования Java, исключение – это специальный объект, описывающий исключительную ситуацию, которая возникла в некоторой части программного кода. Объект представляющий исключение, генерируется в момент возникновения исключительной ситуации. После возникновения критической (исключительной) ситуации исключение перехватывается и обрабатывается. Таким образом, возникает понятие генерирования исключения. Генерирование исключения – процесс создания объекта, который описывает данное исключение.

3. Какими способами могут генерироваться исключения?

В языке Java исключения могут генерироваться одним из двух способов:

4. В каких случаях вызывается стандартный обработчик исключений Java?

Стандартный обработчик исключений Java вызывается в случаях, когда программа:

Если программа содержит собственный код try…catch для обработки данной исключительной ситуации, тогда стандартный обработчик исключений не вызывается.

5. Какие ключевые слова используются для обработки исключений в Java?

Для обработки исключений в Java используются следующие ключевые слова:

В языке Java можно вручную перехватывать исключения (исключительные ситуации) и соответствующим образом обрабатывать их. Важно, чтобы при возникновении исключительной ситуации программа не прекратила свое выполнение.

В блоке try размещаются операторы программы, которые нужно проконтролировать и, в случае возникновения исключительной ситуации, сгенерировать исключение. Внутри блока try могут быть вызваны различные методы, способные сгенерировать то или иное исключение. Однако, обработчик исключения будет только один.

Операторы try и catch составляют единое целое. Оператор finally может отсутствовать.

7. Пример генерирования исключения и его перехват стандартным обработчиком исключений Java

Если в программе отсутствует собственный блок try…catch перехвата исключения, будет вызван стандартный обработчик исключения. В примере демонстрируется вызов стандартного обработчика.

Текст класса DemoExceptions следующий:

Если в другом классе использовать метод DivNumbers() следующим образом

то будет вызванный стандартный обработчик Java, который выведет следующее сообщение

8. Пример перехвата и обработки исключения с помощью оператора try…catch

Текст класса DemoExceptions следующий

Теперь, при использовании метода DivNumbers2() в другом классе

система выдаст следующий результат после запуска программы на выполнение

Можно изменить вывод собственного сообщения об исключении на стандартное сообщение. В этом случае нужно изменить текст в блоке catch на следующий

После изменений, результат выполнения программы будет такой

Текст класса DemoExceptions следующий

будет вызываться всегда. И перед оператором

Использование метода DivNumbers3() в другом классе может быть следующим

Результат выполнения программы

10. Как реализовать вывод описания исключения? Пример

В результате программа будет выводить следующий результат

11. Пример перехвата нескольких исключительных ситуаций (несколько операторов catch )

Реализация класса DivArrays следующая

Использование класса в другом программном коде

Источник

Собеседование по Java — исключения (exceptions) (вопросы и ответы)

Список вопросов и ответов по теме «Исключения в Java».

К списку вопросов по всем темам

Вопросы

1. Дайте определение понятию “исключение”
2. Какова иерархия исключений.
3. Можно/нужно ли обрабатывать ошибки jvm?
4. Какие существуют способы обработки исключений?
5. О чем говорит ключевое слово throws?
6. В чем особенность блока finally? Всегда ли он исполняется?
7. Может ли не быть ни одного блока catch при отлавливании исключений?
8. Могли бы вы придумать ситуацию, когда блок finally не будет выполнен?
9. Может ли один блок catch отлавливать несколько исключений (с одной и разных веток наследований)?
10. Что вы знаете об обрабатываемых и не обрабатываемых (checked/unchecked) исключениях?
11. В чем особенность RuntimeException?
12. Как написать собственное (“пользовательское”) исключение? Какими мотивами вы будете руководствоваться при выборе типа исключения: checked/unchecked?
13. Какой оператор позволяет принудительно выбросить исключение?
14. Есть ли дополнительные условия к методу, который потенциально может выбросить исключение?
15. Может ли метод main выбросить исключение во вне и если да, то где будет происходить обработка данного исключения?
16. Если оператор return содержится и в блоке catch и в finally, какой из них “главнее”?
17. Что вы знаете о OutOfMemoryError?
18. Что вы знаете о SQLException? К какому типу checked или unchecked оно относится, почему?
19. Что такое Error? В каком случае используется Error. Приведите пример Error’а.
20. Какая конструкция используется в Java для обработки исключений?
21. Предположим, есть блок try-finally. В блоке try возникло исключение и выполнение переместилось в блок finally. В блоке finally тоже возникло исключение. Какое из двух исключений “выпадет” из блока try-finally? Что случится со вторым исключением?
22. Предположим, есть метод, который может выбросить IOException и FileNotFoundException в какой последовательности должны идти блоки catch? Сколько блоков catch будет выполнено?

Ответы

1. Дайте определение понятию “исключение”

Исключение — это проблема(ошибка) возникающая во время выполнения программы. Исключения могут возникать во многих случаях, например:

Все исключения в Java являются объектами. Поэтому они могут порождаться не только автоматически при возникновении исключительной ситуации, но и создаваться самим разработчиком.

2. Какова иерархия исключений.

Что такое ошибка а что такое исключительная ситуация java. Смотреть фото Что такое ошибка а что такое исключительная ситуация java. Смотреть картинку Что такое ошибка а что такое исключительная ситуация java. Картинка про Что такое ошибка а что такое исключительная ситуация java. Фото Что такое ошибка а что такое исключительная ситуация java

Исключения делятся на несколько классов, но все они имеют общего предка — класс Throwable. Его потомками являются подклассы Exception и Error.

Исключения (Exceptions) являются результатом проблем в программе, которые в принципе решаемы и предсказуемы. Например, произошло деление на ноль в целых числах.

Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память, доступная виртуальной машине. Программа дополнительную память всё равно не сможет обеспечить для JVM.

В Java все исключения делятся на два типа: контролируемые исключения (checked) и неконтролируемые исключения (unchecked), к которым относятся ошибки (Errors) и исключения времени выполнения (RuntimeExceptions, потомок класса Exception).

Контролируемые исключения представляют собой ошибки, которые можно и нужно обрабатывать в программе, к этому типу относятся все потомки класса Exception (но не RuntimeException).

3. Можно/нужно ли обрабатывать ошибки jvm?

Обрабатывать можно, но делать этого не стоит. Разработчику не предоставлены инструменты для обработки ошибок системы и виртуальной машины.

4. Какие существуют способы обработки исключений?

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

Источник

Что такое ошибка а что такое исключительная ситуация java

Основные навыки и понятия

В этой главе речь пойдет об обработке исключительный ситуаций, или просто исключений. Исключение — это ошибка, возникающая в процессе выполнения программы. Используя подсистему обработки исключений Java, можно контролировать реакцию программы на появление ошибок в ходе ее выполнения. Средства обработки исключений в том или ином виде присутствуют практически во всех современных языках программирования. Можно смело утверждать, что в Java подобные инструментальные средства отличаются большей гибкостью, более понятны и удобны в употреблении по сравнению с большинством других языков программирования.

Преимущество обработки исключений заключается в том, что она автоматически предусматривает реакцию на многие ошибки, избавляя от необходимости писать вручную соответствующий код. Например, в некоторых старых языках программирования предусматривается возврат специального кода при возникновении ошибки в ходе выполнения метода. Этот код приходится проверять вручную при каждом вызове метода. Такой подход к обработке ошибок вручную трудоемок и чреват погрешностями. Обработка исключений упрощает этот процесс, давая возможность определять в программе блок кода, называемый обработчиком исключения и автоматически выполняющийся при возникновении ошибки. Это избавляет от необходимости проверять вручную, насколько удачно или неудачно была выполнена та или иная операция или вызов метода. Если возникнет ошибка, все необходимые действия по ее обработке выполнит обработчик исключений.

В Java определены стандартные исключения для наиболее часто встречающихся программных ошибок, в том числе деления на нуль или попытки открыть несуществующий файл. Для того чтобы обеспечить требуемую реакцию на конкретную ошибку, в программу следует включить соответствующий обработчик событий. Исключения широко применяются в библиотеке Java API.

В Java все исключения представлены отдельными классами. Все классы исключений являются потомками класса Throwable. Так, если в программе возникнет исключительная ситуация, будет сгенерирован объект класса, соответствующего определенному типу исключения. У класса Throwable имеются два непосредственных подкласса: Exception и Error. Исключения типа Error относятся к ошибкам, возникающим в виртуальной машине Java, а не в прикладной программе. Контролировать такие исключения невозможно, поэтому реакция на них в прикладной программе, как правило, не предусматривается. В связи с этим исключения данного типа не будут описываться в этой книге.

Ошибки, связанные с выполнением действий в программе, представлены отдельными подклассами, производными от класса Exception. К этой категории, в частности, относятся ошибки деления на нуль, выхода за границы массива и обращения к файлам. Подобные ошибки следует обрабатывать в самой программе. Важным подклассом, производным от Exception, является класс RuntimeException, который служит для представления различных видов ошибок, часто встречающихся при выполнении программ.

Общее представление об обработке исключений

Для обработки исключений в Java предусмотрены пять ключевых слов: try, catch, throw, throws и finally. Они образуют единую подсистему, в которой использование одного ключевого слова почти всегда автоматически влечет за собой употребление другого. Каждое из упомянутых выше ключевых слов будет подробно рассмотрено далее в этой главе. Но прежде следует дать общее представление об их роли в процессе обработки исключений. Поэтому ниже поясняется вкратце, каким образом они действуют.

Операторы, в которых требуется отслеживать появление исключений, помещаются в блок try. Если в блоке try будет сгенерировано исключение, его можно перехватить и обработать нужным образом. Системные исключения генерируются автоматически. А для того чтобы сгенерировать исключение вручную, следует воспользоваться ключевым словом throw. Иногда возникает потребность обрабатывать исключения за пределами метода, в котором они возникают, и для этой цели служит ключевое слово throws. Если же некоторый фрагмент кода должен быть выполнен обязательно и независимо от того, возникнет исключение или нет, его следует поместить в блок finally.

Использование ключевых слов try и catch

Основными языковыми средствами обработки исключений являются ключевые слова try и catch. Они используются совместно. Это означает, что нельзя указать ключевое слово catch в коде, не указав ключевое слово try. Ниже приведена общая форма записи блоков try/catch, предназначенных для обработки исключений.

В скобках, следующих за ключевым словом catch, указываются тип исключения и переменная, ссылающаяся на объект данного типа. Когда возникает исключение, оно перехватывается соответствующим оператором catch, обрабатывающим это исключение. Как следует из приведенной выше общей формы записи, с одним блоком try может быть связано несколько операторов catch. Тип исключения определяет, какой именно оператор catch будет выполняться. Так, если тип исключения соответствует типу оператора catch, то именно он и будет выполнен, а остальные операторы catch — пропущены. При перехвате исключения переменной, указанной в скобках после ключевого слова catch, присваивается ссылка на объект_исключения.

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

На заметку. В версии JDK 7 внедрена новая форма оператора try, поддерживающая автоматическое управления ресурсами и называемая оператором try с ресурсами. Более подробно она описывается в главе 10 при рассмотрении потоков ввода-вывода, в том числе и тех, что связаны с файлами, поскольку потоки ввода-вывода относятся к числу ресурсов, наиболее употребительных в прикладных программах.

Простой пример обработки исключений

Рассмотрим простой пример, демонстрирующий перехват и обработку исключения. Как известно, попытка обратиться за границы массива приводит к ошибке, и виртуальная машина Java генерирует соответствующее исключение ArraylndexOutOf BoundsException. Ниже приведен код программы, в которой намеренно создаются условия для появления данного исключения, которое затем перехватывается.

Результат выполнения данной программы выглядит следующим образом:

Несмотря на всю простоту данного примера программы, он наглядно демонстрирует несколько важных особенностей обработки исключений. Во-первых, код, подлежащий проверке на наличие ошибок, помещается в блок try. И во-вторых, когда возникает исключение (в данном случае это происходит при попытке обратиться за границы массива), выполнение блока try прерывается и управление получает блок catch. Следовательно, явного обращения к блоку catch не происходит, но переход к нему осуществляется лишь при определенном условии, возникающем в ходе выполнения программы. Так, оператор вызова метода println(), следующий за выражением, в котором происходит обращение к несуществующему элементу массива, вообще не выполняется. По завершении блока catch выполнение программы продолжается с оператора, следующего за этим блоком. Таким образом, обработчик исключений предназначен для устранения программных ошибок, приводящих к исключительным ситуациям, а также для обеспечения нормального продолжения исполняемой программы.

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

на следующую строку кода:

Теперь исключение не возникнет и блок catch не выполнится.

Важно понимать, что исключения отслеживаются во всем коде в блоке try. К их числу относятся исключения, которые могут быть сгенерированы методом, вызываемым из блока try. Исключения, возникающие в вызываемом методе, перехватываются операторами в блоке catch, связанном с блоком try. Правда, это произойдет лишь в том случае, если метод не обрабатывает исключения самостоятельно. Рассмотрим в качестве примера следующую программу:

Выполнение этой версии программы дает такой же результат, как и при выполнении ее предыдущей версии. Этот результат приведен ниже.

Метод genException() вызывается из блока try, и поэтому генерируемое, но не перехватываемое в нем исключение перехватывается далее в блоке catch в методе main(). Если бы метод genException() сам перехватывал исключение, оно вообще не дошло бы до метода main().

Последствия неперехвата исключений

Перехват стандартного исключения Java, продемонстрированный в предыдущем примере, позволяет предотвратить завершение программы вследствие ошибки. Генерируемое исключение должно быть перехвачено и обработано. Если исключение не обрабатывается в программе, оно будет обработано виртуальной машиной Java. Но дело в том, что по умолчанию виртуальная машина Java аварийно завершает программу, выводя сообщение об ошибке и трассировку стека исключений. Допустим, в предыдущем примере попытка обращения за границы массива не отслеживается и исключение не перехватывается, как показано ниже.

При появлении ошибки, связанной с обращением за границы массива, выполнение программы прекращается и выводится следующее сообщение:

Оно полезно на этапе отладки, но пользователям программы эта информация вряд ли нужна. Именно поэтому очень важно, чтобы программы обрабатывали исключения самостоятельно и не поручали эту задачу виртуальной машине Java.

Как упоминалось выше, тип исключения должен соответствовать типу, указанному в операторе catch. В противном случае исключение не будет перехвачено. Так, в приведенном ниже примере программы делается попытка перехватить исключение, связанное с обращением за границы массива, с помощью оператора catch, в котором указан тип ArithmeticException еще одного встроенного в Java исключения. При неправильном обращении к массиву будет сгенерировано исключение ArraylndexOutOfBoundsException, не соответствующее типу, указанному в операторе catch. В результате программа будет завершена аварийно.

Ниже приведен результат выполнения данной программы.

Нетрудно заметить, что оператор catch, в котором указан тип исключения ArithmeticException, не может перехватить исключение ArraylndexOutOfBoundsException.

Обработка исключений — изящный способ устранения программных ошибок

Одно из главных преимуществ обработки исключений заключается в том, что она позволяет вовремя отреагировать на ошибку в программе и затем продолжить ее выполнение. В качестве примера рассмотрим еще одну программу, в которой элементы одного массива делятся на элементы другого. Если при этом происходит деление на нуль, то генерируется исключение ArithmeticException. Обработка подобного исключения заключается в том, что программа уведомляет об ошибке и затем продолжает свое выполнение. Таким образом, попытка деления на нуль не приведет к аварийному завершению программы из-за ошибки при ее выполнении. Вместо этого ошибка обрабатывается изящно, не прерывая выполнение программы.

Результат выполнения данной программы выглядит следующим образом:

Данный пример демонстрирует еще одну важную особенность: обработанное исключение удаляется из системы. Иными словами, на каждом шаге цикла блок try выполняется в программе сызнова, а все возникшие ранее исключения считаются обработанными. Благодаря этому в программе могут обрабатываться повторяющиеся ошибки.

Применение нескольких операторов catch

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

Выполнение этой программы дает следующий результат:

Как подтверждает приведенный выше результат выполнения программы, в каждом блоке оператора catch обрабатывается свой тип исключения.

Вообще говоря, выражения с операторами catch проверяются в том порядке, в котором они встречаются в программе. И выполняется лишь тот из них, который соответствует типу возникшего исключения. А остальные блоки операторов catch просто игнорируются.

Перехват исключений, генерируемых подклассами

В отношении подклассов следует отметить еще одну интересную особенность применения нескольких операторов catch: условие перехвата исключений для суперкласса будет справедливо и для любых его подклассов. Например, класс Throwable является суперклассом для всех исключений, поэтому для перехвата всех возможных исключений в операторах catch следует указывать тип Throwable. Если же требуется перехватывать исключения типа суперкласса и типа подкласса, то в блоке операторов первым должен быть указан тип исключения, генерируемого подклассом. В противном случае вместе с исключением типа суперкласса будут перехвачены и все исключения производных от него классов. Это правило соблюдается автоматически, и если указать первым тип исключения, генерируемого суперклассом, то будет создан недостижимый код, поскольку условие перехвата исключения, генерируемого подклассом, никогда не будет выполнено. А ведь недостижимый код в Java считается ошибкой.

Рассмотрим в качестве примера следующую программу

Ниже приведен результат выполнения данной программы.

В данном случае оператор catch (Throwable) перехватывает все исключения, кроме ArraylndexOutOfBoundsException. Соблюдение правильного порядка следования операторов catch приобретает особое значение в том случае, когда исключения генерируются в самой программе.

Вложенные блоки try

Блоки try могут быть вложенными друг в друга. Исключение, возникшее во внутреннем блоке try и не перехваченное связанным с ним блоком catch, распростра¬няется далее во внешний блок try и обрабатывается связанным с ним блоком catch. Такой порядок обработки исключений демонстрируется в приведенном ниже примере программы, где исключение ArraylndexOutOfBoundsException не перехватывается во внутреннем блоке catch, но обрабатывается во внешнем.

Выполнение этой программы может дать, например, следующий результат:

В данном примере исключение, которое может быть обработано во внутреннем блоке try (в данном случае ошибка деления на нуль), не мешает дальнейшему выполнению программы. А вот ошибка превышения границ массива перехватывается во внешнем блоке try, что приводит к аварийному завершению программы.

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

В предыдущих примерах программ обрабатывались исключения, автоматически генерируемые виртуальной машиной Java. Но генерировать исключения можно и вручную, используя для этого оператор throw. Ниже приведена общая форма этого оператора.

где объект_исключения должен быть объектом класса, производного от класса Throwable.

Ниже приведен пример программы, демонстрирующий применение оператора throw. В этой программе исключение ArithmeticException генерируется вручную.

Выполнение этой программы дает следующий результат:

Обратите внимание на то, что исключение ArithmeticException генерируется с помощью ключевого слова new в операторе throw. Дело в том, что оператор throw генерирует исключение в виде объекта. Поэтому после ключевого слова throw недостаточно указать только тип исключения, нужно еще создать объект для этой цели.

Повторное генерирование исключений

Исключение, перехваченное блоком catch, может быть повторно сгенерировано для обработки другим аналогичным блоком. Чаще всего повторное генерирование исключений применяется с целью предоставить разным обработчикам доступ к исключению. Так, например, повторное генерирование имеет смысл в том случае, если один обработчик оперирует одним свойством исключения, а другой обработчик ориентирован на другое его свойство. Повторно сгенерированное исключение не может быть перехвачено тем же самым блоком catch. Оно распространяется в другие блоки catch.

Ниже приведен пример программы, демонстрирующий повторное генерирование исключений.

В данной программе ошибка деления на нуль обрабатывается локально в методе genException(), а при попытке обращения за границы массива исключение генерируется повторно. На этот раз оно перехватывается в методе main().

Подробнее о классе Throwable

В приведенных до сих примерах программ только перехватывались исключения, но не выполнялось никаких действий над представляющими их объектами. В выражении оператора catch указываются тип исключения и параметр, принимающий объект исключения. А поскольку все исключения представлены подклассами, производными от класса Throwable, то они поддерживают методы, определенные в этом классе. Некоторые наиболее употребительные методы из класса Throwable приведены в табл. 9.1.

Таблица 9.1. Наиболее употребительные методы из класса Throwable

МетодОписание
Throwable filllnStackTrace()Возвращает объект типа Throwable, содержащий полную трассировку стека исключений. Этот объект пригоден для повторного генерирования исключений
String getLocalizedMessage()Возвращает описание исключения, локализованное по региональным стандартам
String getMessage()Возвращает описание исключения
void printStackTrace()Выводит трассировку стека исключений
void printStackTrace(PrintStream stream)Выводит трассировку стека исключений в указанный поток
void printStackTrace(PrintWriter stream)Направляет трассировку стека исключений в указанный поток
String toString()Возвращает объект типа String, содержащий полное описание исключения. Этот метод вызывается из метода println() при выводе объекта типа Throwable

Среди методов, определенных в классе Throwable, наибольший интерес представляют методы pr intStackTrace() и toString(). С помощью метода printStackTrace() можно вывести стандартное сообщение об ошибке и запись последовательности вызовов методов, которые привели к возникновению исключения, А метод toString() позволяет получить стандартное сообщение об ошибке. Этот метод также вызывается в том случае, когда объект исключения передается в качестве параметра методу println(). Применение этих методов демонстрируется в следующем примере программы:

Результат выполнения данной программы выглядит следующим образом:

Использование ключевого слова finally

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

Для того чтобы определить код, который должен выполняться по завершении блока try/catch, нужно указать блок finally в конце последовательности операторов try/catch. Ниже приведена общая форма записи блока try/catch вместе с блоком finally.

Блок finally выполняется всегда по завершении блока try/catch независимо от того, какое именно условие к этому привело. Следовательно, блок finally получит управление как при нормальной работе программы, так и при возникновении ошибки. Более того, он будет вызван даже в том случае, если в блоке try или в одном из блоков catch будет присутствовать оператор return для немедленного возврата из метода.

Ниже приведен краткий пример программы, демонстрирующий применение блока finally.

В результате выполнения данной программы получается следующий результат:

Нетрудно заметить, что блок finally выполняется независимо от того, каким об¬ разом завершается блок try/catch.

Использование ключевого слова throws

Иногда исключения нецелесообразно обрабатывать в том методе, в котором они возникают. В таком случае их следует указывать с помощью ключевого слова throws. Ниже приведена общая форма объявления метода, в котором присутствует ключевое слово throws.

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

Возможно, вам покажется странным, что в ряде предыдущих примеров ключевое слово throws не указывалось при генерировании исключений за пределами методов. Дело в том, что исключения, генерируемые подклассом Error или RuntimeException, можно и не указывать в списке оператора throws. Исполняющая система Java по умолчанию предполагает, что метод может их генерировать. А исключения всех остальных типов следует непременно объявить с помощью ключевого слова throws. Если этого не сделать, возникнет ошибка при компиляции.

Пример применения оператора throws уже был представлен ранее в этой книге. Напомним, что при организации ввода с клавиатуры в метод main() потребовалось включить следующее выражение:

Теперь вы знаете, зачем это было нужно. При вводе данных может возникнуть исключение IOException, а на тот момент вы еще не знали, как оно обрабатывается. Поэтому мы и указали, что исключение должно обрабатываться за пределами метода main(). Теперь, ознакомившись с исключениями, вы сможете без труда обработать исключение IOException самостоятельно.

Рассмотрим пример, в котором осуществляется обработка исключения IOException. В методе prompt() отображается сообщение, а затем выполняется ввод символов с клавиатуры. Такой ввод данных может привести к возникновению исключения IOException. Но это исключение не обрабатывается в методе prompt(). Вместо этого в объявлении метода указан оператор throws, т.е. обязанности по обработке данного исключению поручаются вызывающему методу. В данном случае вызывающим является метод main(), в котором и перехватывается исключение.

Обратите внимание на одну особенность приведенного выше примера. Класс IOException относится к пакету java. io. Как будет разъяснено в главе 10, в этом пакете содержатся многие языковые средства Java для организации ввода-вывода. Следовательно, пакет java.io можно импортировать, а в программе указать только имя класса IOException.

Новые средства обработки исключений, внедренные в версии JDK 7

С появлением версии JDK 7 механизм обработки исключений в Java был значительно усовершенствован благодаря внедрению трех новых средств. Первое из них поддерживает автоматическое управление ресурсами, позволяющее автоматизировать процесс освобождения таких ресурсов, как файлы, когда они больше не нужны. В основу этого средства положена расширенная форма оператора try, называемая оператором try с ресурсами и описываемая в главе 10 при рассмотрении файлов. Второе новое средство называется многократным перехватом, а третье — окончательным или более точным повторным генерированием исключений. Два последних средства рассматриваются ниже.

Многократный перехват позволяет перехватывать два или более исключения одним оператором catch. Как пояснялось ранее, после оператора try можно (и даже принято) указывать два или более оператора catch. И хотя каждый блок оператора catch, как правило, содержит свою особую кодовую последовательность, нередко в двух или более блоках оператора catch выполняется одна и та же кодовая последовательность, несмотря на то, что в них перехватываются разные исключения. Вместо того чтобы перехватывать каждый тип исключения в отдельности, теперь можно воспользоваться единым блоком оператора catch для обработки исключений, не дублируя код.

Для организации многократного перехвата следует указать список исключений в одном операторе catch, разделив их типы оператором поразрядного ИЛИ. Каждый параметр многократного перехвата неявно указывается как final. (По желанию модификатор доступа final можно указать и явным образом, но это совсем не обязательно.) А поскольку каждый параметр многократного перехвата неявно указывается как final, то ему нельзя присвоить новое значение.

В приведенной ниже строке кода показывается, каким образом многократный перехват исключений ArithmeticException и ArraylndexOutOfBoundsException указывается в одном операторе catch.

Ниже приведен краткий пример программы, демонстрирующий применение многократного перехвата исключений.

В данном примере программы исключение ArithmeticException генерируется при попытке деления на нуль, а исключение ArraylndexOutOfBoundsException — при попытке обращения за границы массива chrs. Оба исключения перехватываются одним оператором catch.

Средство более точного повторного генерирования исключений ограничивает этот процесс лишь теми проверяемыми типами исключений, которые генерируются в соответствующем блоке try и не обрабатываются в предыдущем блоке оператора catch, а также относятся к подтипу или супертипу указываемого параметра. И хотя такая возможность требуется нечасто, ничто не мешает теперь воспользоваться ею в полной мере. А для организации окончательного повторного генерирования исключений параметр оператора catch должен быть, по существу, указан как final. Это означает, что ему нельзя присвоить новое значение в блоке catch. Он может быть указан как final явным образом, хотя это и не обязательно.

Встроенные в Java исключения

В стандартном пакете java. lang определены некоторые классы, представляющие стандартные исключения Java. Часть из них использовалась в предыдущих примерах программ. Наиболее часто встречаются исключения из подклассов стандартного класса RuntimeException. А поскольку пакет java. lang импортируется по умолчанию во все программы на Java, то исключения, производные от класса RuntimeException, становятся доступными автоматически. Их даже обязательно включать в список оператора throws. В терминологии языка Java такие исключения называют непроверяемыми, поскольку компилятор не проверяет, обрабатываются или генерируются подобные исключения в методе. Непроверяемые исключения, определенные в пакете java.lang, приведены в табл. 9.2, тогда как в табл. 9.3 — те исключения из пакета j ava. lang, которые следует непременно включать в список оператора throws при объявлении метода, если, конечно, в методе содержатся операторы, способные генерировать эти исключения, а их обработка не предусмотрена в теле метода. Такие исключения принято называть проверяемыми. В Java предусмотрен также ряд других исключений, определения которых содержатся в различных библиотеках классов. К их числу можно отнести упоминавшееся ранее исключение IOException.

Таблица 9.2. Непроверяемые исключения, определенные в пакете java.lang

ИсключениеОписание
ArithmeticExceptionАрифметическая ошибка, например попытка деления на нуль
ArraylndexOutOfBoundsExceptionПопытка обращения за границы массива
ArrayStoreExceptionПопытка ввести в массив элемент, несовместимый с ним по типу
ClassCastExceptionНедопустимое приведение типов
EnumConstNotPresentExceptionПопытка использования нумерованного значения, которое не было определено ранее
IllegalArgumentExceptionНедопустимый параметр при вызове метода
IllegalMonitorStateExceptionНедопустимая операция контроля, например, ожидание разблокировки потока
IllegalStateExceptionНедопустимое состояние среды выполнения или приложения
IllegalThreadStateExceptionЗапрашиваемая операция несовместима с текущим состоянием потока
IndexOutOfBoundsExceptionНедопустимое значение индекса
NegativeArraySizeExceptionСоздание массива отрицательного размера
NullPointerExceptionНедопустимое использование пустой ссылки
NumberFormatExceptionНеверное преобразование символьной строки в число
SecurityExceptionПопытка нарушить систему защиты
StringlndexOutOfBoundsПопытка обращения к символьной строке за ее границами
TypeNotPresentExceptionНеизвестный тип
UnsupportedOperationExceptionНеподдерживаемая операция

Таблица 9.3. Проверяемые исключения, определенные в пакете java.lang

ИсключениеОписание
ClassNotFoundExceptionКласс не найден
CloneNotSupportedExceptionПопытка клонирования объекта, не реализующего интерфейс Cloneable
IllegalAccessExceptionДоступ к классу запрещен
InstantiationExceptionПопытка создания объекта абстрактного класса или интер¬фейса
InterruptedExceptionПрерывание одного потока другим
NoSuchFieldExceptionТребуемое поле не существует
NoSuchMethodExceptionТребуемый метод не существует
ReflectiveOperationExceptionСуперкласс исключений, связанных с рефлексией (добавлен в версии JDK 7)

Создание подклассов, производных от класса Exception

Несмотря на то что встроенные в Java исключения позволяют обрабатывать большинство ошибок, механизм обработки исключений не ограничивается только этими ошибками. В частности, можно создавать исключения для обработки потенциальных ошибок в прикладной программе. Создать исключение несложно. Для этого достаточно определить подкласс, производный от класса Exception, который, в свою очередь, является подклассом, порожденным классом Throwable. В создаваемый подкласс не обязательно включать реализацию каких-то методов. Сам факт существования такого подкласса позволяет использовать его в качестве исключения.

В классе Exception не определены новые методы. Он лишь наследует методы, предоставляемые классом Throwable. Таким образом, все исключения, включая и создаваемые вами, содержат методы класса Throwable. Конечно же, вы вольны переопределить в создаваемом вами классе один или несколько методов.

Ниже приведен пример, в котором создается исключение NonlntResultException. Оно генерируется в том случае, если результатом деления двух целых чисел является дробное число. В классе NonlntResultException содержатся два поля, предназначенные для хранения целых чисел, а также конструктор. В нем также переопределен метод toString(), что дает возможность выводить описание исключения с помощью метода println().

Результат выполнения данной программы выглядит следующим образом:

Пример для опробования 9.1. Добавление исключений в класс очереди

В этом проекте предстоит создать два класса исключении, которые будут использоваться классом очереди, разработанным в примере для опробования 8.1. Эти исключения должны указывать на переполнение и опустошение очереди, а генерировать их будут методы put() и get() соответственно. Ради простоты эти исключения добавляются в класс FixedQueue, но вы можете без труда внедрить их в любые другие классы очереди, разработанные в примере для опробования 8.1.

Упражнение для самопроверки по материалу главы 9

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *