- •ОГЛАВЛЕНИЕ
- •ВВЕДЕНИЕ
- •ГЛАВА 1. ПРИНЦИПЫ ООП. КЛАССЫ И ОБЪЕКТЫ
- •1.1 Основные принципы ООП
- •1.2 Достоинства ООП
- •1.3 Недостатки ООП
- •1.4 Классы и объекты
- •1.5 Члены класса
- •1.6 Модификаторы объявления класса
- •1.7 Пакеты
- •1.8 Понятие имени
- •1.9 Понятие модуля компиляции
- •1.10 Поля
- •1.11 Управление доступом
- •1.12 Создание объектов
- •1.13 Конструкторы
- •1.14 Блоки инициализации
- •1.15 Статическая инициализация
- •1.16 Методы
- •1.16.1 Модификаторы методов
- •1.16.2 Статические методы
- •1.16.3 Вызов метода
- •1.16.4 Выполнение метода и возврат из него
- •1.16.5 Параметры метода
- •1.16.6 Применение методов для управления доступом
- •1.16.7 Ключевое слово this
- •1.16.8 Перегруженные методы
- •1.16.9 Метод main
- •1.16.10 Методы native
- •ГЛАВА 2. ОСНОВЫ ЛЕКСИКИ
- •2.1 Комментарии
- •2.2 Служебные слова
- •2.3 Идентификаторы
- •2.4 Литералы
- •2.4.1 Целочисленные литералы
- •2.4.2 Литералы с плавающей точкой
- •2.4.3 Логические литералы
- •2.4.4 Символьные литералы
- •2.4.5 Строковые литералы
- •2.5 Операторы
- •2.6 Разделители
- •2.7 Переменные
- •2.8 Простые типы
- •2.8.1 Целочисленные типы
- •byte
- •short
- •long
- •2.8.2 Числовые типы с плавающей точкой
- •float
- •double
- •2.8.3 Приведение типа
- •2.8.4 Автоматическое преобразование типов в выражениях
- •2.8.5 Символьный тип
- •2.8.6 Логический тип
- •2.9 Массивы
- •2.9.1 Многомерные массивы
- •2.9.2 Инициализация массивов
- •2.10 Операторы
- •2.10.1 Арифметические операторы
- •Операторы арифметических действий
- •Оператор деления по модулю
- •Операторы арифметических действий с присваиванием
- •Целочисленная арифметика
- •Арифметика с плавающей запятой
- •2.10.2 Инкремент и декремент
- •2.10.3 Целочисленные битовые операторы
- •Операторы битовой арифметики
- •Оператор побитового сдвига влево
- •Операторы побитового сдвига вправо
- •Операторы битовой арифметики с присваиванием
- •2.10.4 Операторы сравнения
- •2.10.5 Логические операторы
- •2.10.6 Оператор проверки соответствия типа
- •2.10.7 Условный тернарный оператор
- •2.10.8 Приоритеты операторов
- •2.11 Управление выполнением метода
- •2.11.1 Завершение работы метода
- •2.11.2 Ветвление
- •2.11.3 Циклы
- •while
- •do-while
- •2.11.4 Прерывание блоков инструкций
- •2.11.5 Переход на следующий виток цикла
- •2.11.6 Блок переключателей
- •ГЛАВА 3. ИСКЛЮЧЕНИЯ
- •3.1 Общие сведения об исключениях
- •3.2 Инструкция throw
- •3.3 Предложения throws
- •3.4 Предложения throws и переопределение методов
- •3.5 Предложения throws и методы native
- •3.6 Блок try-catch-finally
- •ГЛАВА 4. НАСЛЕДОВАНИЕ
- •4.1 Расширенный класс. Конструкторы расширенных классов
- •4.2 Порядок выполнения конструкторов
- •4.3 Переопределение методов при наследовании
- •4.4 Сокрытие полей
- •4.5 Доступ к унаследованным членам класса
- •4.6 Возможность доступа и переопределение
- •4.7 Сокрытие статических членов
- •4.8 Служебное слово super
- •4.9 Совместимость и преобразование типов
- •4.9.1 Совместимость
- •4.9.2 Явное преобразование типов
- •4.10 Проверка типа
- •4.11 Завершённые методы и классы
- •4.12 Абстрактные методы и классы
- •4.13 Класс Object
- •4.13.1 Метод сравнения объектов
- •4.13.2 Метод вычисления хеш-кода
- •4.13.3 Метод клонирования объектов
- •4.13.4 Метод получения ссылки на описание класса
- •4.13.5 Метод завершения работы объекта
- •4.13.6 Метод получения строкового представления
- •ГЛАВА 5. ИНТЕРФЕЙСЫ
- •5.1 Пример простого интерфейса
- •5.2 Объявление интерфейса
- •5.3 Константы в интерфейсах
- •5.4 Методы в интерфейсах
- •5.5 Модификаторы в объявлениях интерфейсов
- •5.6 Расширение интерфейсов
- •5.7 Наследование и сокрытие констант
- •5.8 Наследование, переопределение и перегрузка методов
- •5.9 Пустые интерфейсы
- •5.10 Абстрактный класс или интерфейс?
- •СПИСОК СОКРАЩЕНИЙ
- •СПИСОК ЛИТЕРАТУРЫ
В состав класса NoSuchAttributeException, производного от Exception, добавлены конструктор, принимающий в качестве параметра строку наименования атрибута, и публичное поле, предназначенное для ее хранения. В теле конструктора вызывается конструктор базового класса, которому передается строка описания ошибки. С точки зрения кода, выполняющего обработку ошибок, рассмотренный тип исключений достаточно полезен, так как он содержит и внятное описание ошибки, и наименование атрибута, отсутствие которого привело к ее возникновению.
Возможность добавления данных – это только один довод в пользу создания новых типов исключений. Другой, не менее важный, связан с тем, что тип исключения как таковой – это неотъемлемая часть информации об ошибке, поскольку исключения «отлавливаются» в соответствии с их типами. По этой причине класс NoSuchAttributeException стоило создать даже в том случае, если бы нам и не требовались дополнительные поля данных. Вообще говоря, новый тип исключений целесообразно создавать в тех случаях, когда желательно приобрести возможность «отлова» одних исключений, игнорируя при этом другие.
При создании новых типов исключений важно уделять внимание тому, от какого класса исключения вы наследуете, поскольку при этом вы определяете, по сути, подвид существовавшего ранее исключения. Поэтому важно также иметь представление об уже существующих видах исключений, особенно стандартных.
3.2 Инструкция throw
Исключения могут быть выброшены методами и операторами, которые вы используете в своей программе. Кроме того, вы можете выбросить исключение в своём коде, для этого используется инструкция throw, имеющая следующий формат:
throw <Выражение>;
122
где <Выражение> обязано возвращать ссылку на объект типа Throwable. В примере 58 показана генерация описанного ранее исключения NoSuchAttributeException.
Пример 58. Явное выбрасывание исключения
public void replaceValue(String name, Object newValue) throws NoSuchAttributeException {
Attr attr = find(name); if (attr == null)
throw new NoSuchAttributeException(name); attr.setValue(newValue);
}
В теле метода replaceValue() сначала вызывается метод, выполняющий поиск атрибута по заданному имени. Если поиска не удался, объект исключения типа NoSuchAttributeException вначале создается, с передачей его конструктору строки имени атрибута, а затем выбрасывается. Исключение – это объект, поэтому,
прежде всего, его следует явно создать. Если же атрибут с указанным именемсуществует, его текущеезначение заменяется новым.
При выбрасывании исключения выполнение инструкции или выражения, приведшего к исключению, завершается аварийно. Это также приводит к последовательному аварийному завершению всех блоков и методов, участвующих в цепочке вызовов, вплоть до точки программного кода, в которой исключение отлавливается. Если исключение остается необработанным, соответствующий поток вычислений останавливается, но предварительно предоставляется возможность каким-то образом обслужить исключение (с помощью обработчиков исключений потоков и групп потоков).
Если исключение возникло, все действия, предусмотренные в программном коде после инструкции или выражения, вызвавших исключение, далее не выполняются. Если исключение было выброшено в процессе вычисления левостороннего операнда выражения, никакие
123
составляющие правостороннего операнда больше не анализируются. Аналогично, если появление исключения спровоцировал левый аргумент в любой части выражения, все аргументы справа от него игнорируются. Следующим будет выполнен либо «завершающий» блок finally, либо блок catch, обрабатывающий исключение.
Результатом работы инструкции throw служит синхронное (synchronous) исключение – то же самое происходит, например, при целочисленном делении на ноль: исключение возникает как непосредственный итог выполнения определенной инструкции, причем неважно, выбрасывается ли оно явно, командой throw, либо косвенно, исполняющей системой, обнаружившей, например,
факт деления на ноль. Асинхронное (asynchronous) исключение
также возникает при выполнении инструкции, но причина возникновения исключения находится не в этой инструкции.
Асинхронные исключения проявляются в двух ситуациях. Первая связана с внутренними ошибками виртуальной машины Java – такие исключения считаются асинхронными, поскольку их появление провоцируется кодом виртуальной машины, а не инструкциями приложения. Понятно, что с подобными ошибками автору прикладной программы в подавляющем большинстве случаев справиться не удастся. Примером такой ситуации может служить нехватка памяти при создании объектов: место выбрасывания исключения OutOfMemoryException будет определяться, по сути, не выполняемой инструкцией создания объекта, а количеством памяти JVM, указываемом при запуске виртуальноймашины.
Ко второй группе причин возникновения асинхронных исключений относится использование устаревших и не рекомендованных для применения методов (например, Thread.stop), а также подобных им разрешённых методов (например, stopThread) из состава JavaTM
Virtual Machine Debug Interface (JVMDI) – native-интерфейса вирту-
альной машины, позволяющего проверять состояние работающих
124
приложений Java и управлять ими. Такие методы предоставляют возможность генерирования асинхронных исключений различных категорий (объявляемых и необъявляемых) в любой момент на протяжении цикла выполнения конкретного потока вычислений. Подобные механизмы рискованны и опасны просто по своей внутренней природе, поэтому их применение в большинстве случаев не поощряется.
3.3Предложения throws
Впримере 58 в объявлении метода replaceValue() ясно указано, какие объявленные исключения он способен генерировать. Язык требует предоставления подобной информации, поскольку сведения об исключениях, которые могут быть выброшены методом, важны в такой же степени, как и данные о типе возвращаемого им значения. Поэтому логично в объявлении метода указывать не только тип возвращаемого значения, но и список возможных исключений.
Объявляемые методом исключения указываются с помощью предложения throws в виде списка наименований типов исключений, разделяемых символом запятой. В списке обязаны присутствовать те объявляемые исключения, которые генерируются (тем или иным способом) в методе, но не обрабатываются в его теле.
Метод вправе выбрасывать исключения типов, производных от тех, которые объявлены в предложении throws: язык позволяет полиморфным образом использовать объекты производных типов
влюбом контексте, где предусмотрено задание объектов базового типа. Более того, метод способен генерировать исключения нескольких различных классов, производных от одного базового и при этом обнародовать в throws только один базовый класс. Следует, однако, иметь в виду, что при использовании такого
подхода вы лишите программистов, которые будут обращаться к методу, ценной информации о том, какие именно исключения расширенных типов способен выбрасывать метод. С точки зрения
125
удобства использования и возможностей развития кода предложение throws должно быть настолько полным и точным в деталях, насколько это приемлемо в конкретной ситуации.
Часть контракта метода, определяемая предложением throws, строго проверяется на этапе компиляции: метод вправе выбрасывать объявляемые исключения только тех типов, которые явно названы. Выбрасывание объявляемых исключений других типов – как непосредственное, с помощью инструкции throw, так и косвенное, вследствие обращения к другим методам, запрещается. Если в объявлении метода вообще отсутствует предложение throws, это не значит, что не могут быть выброшены какие-либо исключения – речь идёт только о невозможности генерирования объявляемых исключений.
Поскольку типы объявляемых исключений должны быть указаны в предложении throws, отсюда следует, что фрагменты кода, не находящиеся в методах с предложением throws, не вправе выбрасывать объявляемые исключения ни явно, ни косвенно (либо обязаны их явно отлавливать и обрабатывать). Такими фрагментами кода являются блоки инициализации классов (в них можно явно отловить исключение) и инициализаторы полей (никак не могут отлавливать исключения). Однако в действительности блоки инициализации и инициализаторы полей могут выбрасывать объявляемые исключения, но только если блоки и поля не являются статическими, а типы исключений объявлены во всех конструкторах класса. Статические инициализаторы, действительно, никак не могут выбрасывать объявляемые исключения.
Вызывая метод, в определении которого содержится предложение throws с перечнем объявляемых исключений, можете поступить одним из трёх способов:
•отловить исключения и обработать их;
126