![]() |
Spec-Zone .ru
спецификации, руководства, описания, API
|
Содержание | Предыдущий | Следующий | Индекс | Спецификация языка Java Третий Выпуск |
ГЛАВА 11
Когда программа нарушает семантические ограничения языка программирования Java, виртуальная машина Java сигнализирует эту ошибку к программе как исключение. Примером такого нарушения является попытка индексировать вне границ массива. Некоторые языки программирования и их реализации реагируют на такие ошибки, безапелляционно завершая программу; другие языки программирования позволяют реализации реагировать произвольным или непредсказуемым способом. Ни один из этих подходов не является совместимым с целями проекта платформы Java: обеспечить мобильность и устойчивость. Вместо этого язык программирования Java определяет, что исключение будет выдано, когда семантические ограничения будут нарушены и вызовут нелокальную передачу управления от точки, где исключение произошло с точкой, которая может быть определена программистом. Исключение, как говорят, выдается от точки, где это произошло и, как говорят, поймано в точке, которой передается управление.
Программы могут также выдать исключения явно, используя throw
операторы (§14.18).
Явное использование throw
операторы обеспечивают альтернативу старомодному стилю условий ошибки из-за неправильного обращения, возвращая забавные значения, такие как целочисленное значение -1
где отрицательная величина обычно не ожидалась бы. Опыт показывает, что слишком часто такие забавные значения игнорируются или не проверяются на вызывающими сторонами, приводя к программам, которые не устойчивы, показывают нежелательное поведение, или обоих.
Throwable
или один из его подклассов; такой объект может использоваться, чтобы перенести информацию от точки, в которой исключение происходит с обработчиком, который ловит это. Обработчики устанавливаются catch
пункты try
операторы (§14.20). Во время процесса выдачи исключения виртуальная машина Java резко завершает, один за другим, любые выражения, операторы, метод и вызовы конструктора, инициализаторы, и полевые выражения инициализации, которые начали, но не завершили выполнение в текущем потоке. Этот процесс продолжается, пока обработчик не находится, который указывает, что это обрабатывает то определенное исключение, называя класс исключения или суперкласс класса исключения. Если никакой такой обработчик не находится, то метод uncaught-Exception
вызывается для ThreadGroup
это - родитель текущего потока таким образом, каждое усилие прилагается, чтобы избежать позволять исключению идти необработанное.
Механизм исключения платформы Java интегрируется с ее моделью синхронизации (§17), так, чтобы блокировки были выпущены как synchronized
операторы (§14.19) и вызовы synchronized
методы (§8.4.3.6, §15.12) завершаются резко.
Эта глава описывает различные причины исключений (§11.1). Это детализирует, как исключения проверяются во время компиляции (§11.2) и обрабатываются во время выполнения (§11.3). Подробному примеру (§11.4) тогда следует объяснение иерархии исключения (§11.5).
Эти исключения не выдаются в произвольной точке в программе, а скорее в точке, где они определяются как возможный результат выполнения оператора или вычисления выражения.
throw
оператор (§14.18) выполнялся.
stop
из класса Thread
был вызван
Throwable
и экземпляры его подклассов. Эти классы являются, все вместе, классами исключений.throws
пункт для метода (§8.4.6) или конструктор (§8.8.5) должен упомянуть класс того исключения или один из суперклассов класса того исключения. Это время компиляции, проверяя на присутствие обработчиков исключений разрабатывается, чтобы сократить количество исключений, которые должным образом не обрабатываются.
Классы исключений непроверенные являются классом RuntimeException
и его подклассы, и класс Error
и его подклассы. Все другие классы исключений являются проверенными классами исключений. API Java определяет много классов исключений, оба проверенные и непроверенные. Дополнительные классы исключений, оба проверенные и непроверенные, могут быть объявлены программистами. См. §11.5 для описания иерархии класса исключений и некоторые из классов исключений, определенных API Java и виртуальной машиной Java.
Проверенные классы исключений, названные в throws
пункт является частью контракта между конструктором и пользователем метода или конструктором. throws
пункт метода переопределения, возможно, не определяет, что этот метод приведет к выдаче любого проверенного исключения, которое переопределенный метод не разрешается throws
пункт, чтобы бросить. Когда интерфейсы включаются, больше чем одно объявление метода может быть переопределено единственным объявлением переопределения. В этом случае у объявления переопределения должен быть a throws
пункт, который является совместимым со всеми переопределенными объявлениями (§9.4).
Мы говорим, что оператор или выражение могут бросить проверенный тип E исключения, если, согласно правилам, данным ниже, выполнение оператора или выражения может привести к исключению бросаемого типа E.
Явный оператор вызова конструктора может бросить эквивалентность типа E исключения также:
try
оператор может бросить эквивалентность типа E исключения также:
try
блок может бросить E, и E не присваиваем любому catch
параметр try
оператор и любой нет finally
блок присутствует или finally
блок может обычно завершаться; или
catch
блок try
оператор может бросить E и любого нет finally
блок присутствует или finally
блок может обычно завершаться; или
finally
блок присутствует и может бросить E.
Это - ошибка времени компиляции, если инициализатор переменной экземпляра именованного класса может выдать проверенное исключение, если то исключение или один из его супертипов явно не объявляются в пункте бросков каждого конструктора его класса, и у класса есть по крайней мере один явно объявленный конструктор. Инициализатор переменной экземпляра в анонимном классе (§15.9.5) может выдать любые исключения.
Это - ошибка времени компиляции если a catch
выгоды пункта проверенный тип E1 исключения, но там не существует никакой проверенный тип E2 исключения так, что все следующее, содержат:
try
блок, соответствующий catch
пункт может бросить E2
catch
блок немедленного включения try
оператор ловит E2 или супертип E2. Exception
.Error
и его подклассы), освобождаются со времени компиляции, проверяя, потому что они могут произойти во многих точках в программе, и восстановление от них является трудным или невозможным. Программа, объявляя такие исключения была бы нарушена, бессмысленно.RuntimeException
и его подклассы), освобождаются со времени компиляции, проверяя, потому что, в суждении разработчиков языка программирования Java, имея необходимость объявить такие исключения не помог бы значительно в установлении правильности программ. Многие из операций и конструкции языка программирования Java могут привести к исключениям на этапе выполнения. Информация, доступная компилятору, и уровню анализа, который выполняет компилятор, обычно не достаточна, чтобы установить, что такие исключения на этапе выполнения не могут произойти, даже при том, что это может быть очевидно для программиста. Требование, чтобы такие классы исключений были объявлены, просто было бы раздражением программистам.Например, определенный код мог бы реализовать круговую структуру данных, которая, конструкцией, никогда не может включать null
ссылки; программист может тогда быть уверенным это a NullPointerException
не может произойти, но для компилятора было бы трудно доказать это. Технология доказательства теорем, которая необходима, чтобы установить такие глобальные свойства структур данных, выходит за рамки этой спецификации.
catch
пункт a try
оператор (§14.20), который обрабатывает исключение.
Оператор или выражение динамически включаются a catch
пункт, если это появляется в пределах try
блок try
оператор которого catch
пункт является частью, или если вызывающая сторона оператора или выражения динамически включается catch
пункт.
Вызывающая сторона оператора или выражения зависит от того, где это происходит:
newInstance
это выполнялось, чтобы заставить объект создаваться.
static
переменная, тогда вызывающая сторона является выражением, которое использовало класс или интерфейс, чтобы заставить это быть инициализированным. catch
дескрипторы пункта исключение определяется, сравнивая класс объекта, который был брошен в объявленный тип параметра catch
пункт. catch
пункт обрабатывает исключение, если тип его параметра является классом исключения или суперклассом класса исключения. Эквивалентно, a catch
пункт поймает любой объект исключения, который является instanceof
(§15.20.2) объявленный тип параметра.
Передача управления, которая происходит, когда исключение выдается причины резкое завершение выражений (§15.6) и операторы (§14.1) до a catch
с пунктом встречаются, который может обработать исключение; выполнение тогда продолжается, выполняя блок этого catch
пункт. Код, который вызвал исключение, никогда не возобновляется.
Если нет catch
пункт, обрабатывающий исключение, может быть найден, тогда текущий поток (поток, который встречался, исключение) завершается, но только в конце концов finally
пункты были выполнены и метод uncaughtException
был вызван для ThreadGroup
это - родитель текущего потока.
В ситуациях, где это является требуемым, чтобы гарантировать, что один блок кода всегда выполняется за другим, даже если тот другой блок кода завершается резко, a try
оператор с a finally
пункт (§14.20.2) может использоваться.
try
или catch
блок в a try
-finally
или try
-catch
-finally
оператор завершается резко, тогда finally
пункт выполняется во время распространения исключения, даже если никакое соответствие catch
пункт в конечном счете находится. Если a finally
пункт выполняется из-за резкого завершения a try
блок и finally
сам пункт завершается резко, тогда причина резкого завершения try
блок отбрасывается, и новая причина резкого завершения распространяется оттуда.Точные правила для резкого завершения и для ловли исключений определяются подробно со спецификацией каждого оператора в §14 и для выражений в §15 (особенно §15.6).
Надлежащее понимание семантики асинхронных исключений необходимо, если высококачественный машинный код должен быть сгенерирован.
Асинхронные исключения редки. Они происходят только в результате:
stop
методы класса Thread
или ThreadGroup
stop
методы могут быть вызваны одним потоком, чтобы влиять на другой поток или все потоки в указанной группе потока. Они являются асинхронными, потому что они могут произойти в любой точке в выполнении другого потока или потоков. InternalError
считается асинхронным.Платформа Java разрешает небольшому, но ограниченному количеству выполнения происходить прежде, чем асинхронное исключение будет выдано. Этой задержке разрешают позволить оптимизированному коду обнаруживать и выдавать эти исключения в точках, где это практично, чтобы обработать их, повинуясь семантике языка программирования Java.
Простая реализация могла бы опросить относительно асинхронных исключений в точке каждой инструкции передачи управления. Так как у программы есть конечный размер, это обеспечивает привязанный полная задержка обнаружения асинхронного исключения. Так как никакое асинхронное исключение не произойдет между передачами управления, у генератора кода есть некоторая гибкость, чтобы переупорядочить вычисление между передачами управления для большей производительности.
Бумага, Опрашивающая Эффективно на Аппаратных средствах Запаса Марком Фили, Proc. Конференция 1993 года по Функциональному программированию и Архитектуре ЭВМ, Копенгагену, Дания, стр 179-187, рекомендуется как дальнейшее чтение.
Как все исключения, асинхронные исключения точны (§11.3.1).
Если мы выполняем тестовую программу, передавая это параметры:class TestException extends Exception { TestException() { super(); } TestException(String s) { super(s); } } class Test { public static void main(String[] args) { for (String arg :args) { try { thrower(arg); System.out.println("Test \"" + arg + "\" didn't throw an exception"); } catch (Exception e) { System.out.println("Test \"" + arg + "\" threw a " + e.getClass() + "\n with message: " + e.getMessage()); } } } static int thrower(String s) throws TestException { try { if (s.equals("divide")) { int i = 0; return i/i; } if (s.equals("null")) { s = null; return s.length(); } if (s.equals("test")) throw new TestException("Test message"); return 0; } finally { System.out.println("[thrower(\"" + s + "\") done]"); } } }
это производит вывод:divide null not test
[thrower("divide") done] Test "divide" threw a class java.lang.ArithmeticException with message: / by zero [thrower("null") done] Test "null" threw a class java.lang.NullPointerException with message: null [thrower("not") done] Test "not" didn't throw an exception [thrower("test") done] Test "test" threw a class TestException with message: Test message
Этот пример объявляет класс исключений TestException
. main
метод класса Test
вызывает thrower
метод четыре раза, заставляя исключения быть брошенным три из этих четырех раз. try
оператор в методе main
выгоды каждое исключение, что thrower
броски. Ли вызов thrower
завершается обычно или резко, сообщение печатается, описывая, что произошло.
Объявление метода thrower
должен иметь a throws
пункт, потому что это может бросить экземпляры TestException
, который является проверенным классом исключений (§11.2). Ошибка времени компиляции произошла бы если throws
пункт был опущен.
Заметьте что finally
пункт выполняется на каждом вызове thrower
, происходит ли исключение, как показано"[thrower(
...) сделанный]" вывод, который происходит для каждого вызова.
Throwable
(§11.5), прямой подкласс Object
. Классы Exception
и Error
прямые подклассы Throwable
. Класс RuntimeException
прямой подкласс Exception
.Программы могут использовать существующие ранее классы исключений в throw
операторы, или определяют дополнительные классы исключений, как подклассы Throwable
или любого из его подклассов, как соответствующий. Чтобы использовать в своих интересах время компиляции платформы Java, проверяя на обработчики исключений, это типично, чтобы определить самые новые классы исключений как проверенные классы исключений, определенно как подклассы Exception
это не подклассы RuntimeException
.
Exception
суперкласс всех исключений, с которых обычные программы могут хотеть восстановиться. Класс RuntimeException
подкласс класса Exception
. Подклассы RuntimeException
классы исключений непроверенные. Подклассы Exception
кроме RuntimeException
и его подклассы являются всеми проверенными классами исключений.
Класс Error
и его подклассы являются исключениями, с которых обычные программы, как обычно ожидают, не восстановятся. См. спецификацию API Java для подробного описания иерархии исключения.
Класс Error
отдельный подкласс Throwable
, отличный от Exception
в иерархии классов, чтобы позволить программам использовать идиому:
поймать все исключения, от которых восстановление может быть возможным, не фиксируя ошибки, от которых восстановление обычно не возможно.} catch (Exception e) {
LinkageError
когда загрузка, редактирование, подготовка, проверка или ошибка инициализации происходят:
VirtualMachineError
когда внутреннее ограничение ошибки или ресурса препятствует тому, чтобы это реализовало семантику языка программирования Java. См. Спецификацию виртуальной машины Java Второй Выпуск для категорического обсуждения этих ошибок.
Содержание | Предыдущий | Следующий | Индекс | Спецификация языка Java Третий Выпуск |
Авторское право © 1996-2005 Sun Microsystems, Inc. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления через нашу