
- •Кен Арнольд Джеймс Гослинг Дэвид Холмс Язык программирования Java
- •Глава 1 первое знакомство с java 6
- •Глава 2 классы и объекты 29
- •Глава 3 расширение классов 47
- •Глава 4 интерфейсы 70
- •Глава 5 лексемы, операторы и выражения 78
- •Глава 6 порядок выполнения 105
- •Глава 7 исключения 113
- •Глава 8 строки 121
- •Глава 9 потоки 134
- •Глава 10 пакеты 156
- •Глава 11 пакет ввода/вывода 158
- •Глава 12 стандартные вспомогательные средства 183
- •Глава 13 применение типов в программировании 205
- •Глава 14 системное программирование 218
- •Глава1 первое знакомство сjava
- •1.1. С самого начала
- •1.2.Переменные
- •1.3. Комментарии
- •1.4.Именованные константы
- •1.4.1. Символы Unicode
- •1.5.Порядок выполнения
- •1.6.Классы и объекты
- •1.6.1.Создание объектов
- •1.6.2.Статические поля
- •1.6.3.Сборщик мусора
- •1.7.Методы и параметры
- •1.7.1.Вызов метода
- •1.7.2.Ссылка this
- •1.7.3.Статические методы
- •1.8.Массивы
- •1.9.Строковые объекты
- •1.10.Расширение класса
- •1.10.1.Класс Object
- •1.10.2.Вызов методов суперкласса
- •1.11. Интерфейсы
- •1.12.Исключения
- •1.13.Пакеты
- •1.14.Инфраструктура Java
- •1.15.Прочее
- •Глава 2 классы и объекты
- •2.1. Простой класс
- •2.2. Поля
- •2.3. Управление доступом и наследование
- •2.4. Создание объектов
- •2.5. Конструкторы
- •2.6. Методы
- •2.6.1. Значения параметров
- •2.6.2. Применение методов для ограничения доступа
- •2.7. Ссылка this
- •2.8. Перегрузка методов
- •2.9. Статические члены
- •2.9.1. Блоки статической инициализации
- •2.9.2. Статические методы
- •2.10. Сборка мусора и метод finalize
- •2.10.1. Метод finalize
- •2.10.2. Восстановление объектов в методе
- •2.11. Метод main
- •2.12. Метод toString
- •2.13. Родные методы
- •Глава 3 расширение классов
- •3.1. Расширенный класс
- •3.2. Истинное значение protected
- •3.3. Конструкторы в расширенных классах
- •3.3.1. Порядок вызова конструкторов
- •3.4. Переопределение методов и скрытие полей
- •3.4.1. Ключевое слово super
- •3.5. Объявление методов и классов с ключевым словом final
- •3.6. Класс Object
- •3.7. Абстрактные классы и методы
- •3.8. Дублирование объектов
- •3.9. Расширение классов: когда и как
- •3.10. Проектирование расширяемого класса
- •Глава 4 интерфейсы
- •4.1. Пример интерфейса
- •4.2. Одиночное и множественное наследование
- •4.3. Расширение интерфейсов
- •4.3.1. Конфликты имен
- •4.4. Реализация интерфейсов
- •4.5. Использование реализации интерфейса
- •4.6. Для чего применяются интерфейсы
- •Глава 5 лексемы, операторы и выражения
- •5.1. Набор символов
- •5.2. Комментарии
- •5.3. Лексемы
- •5.4. Идентификаторы
- •5.4.1. Зарезервированные слова Java
- •5.5. Примитивные типы
- •5.6. Литералы
- •5.6.1. Ссылки на объекты
- •5.6.2. Логические значения
- •5.6.3. Целые значения
- •5.6.4. Значения с плавающей точкой
- •5.6.5. Символы
- •5.6.6. Строки
- •5.7. Объявления переменных
- •5.7.1. Значение имени
- •5.8. Массивы
- •5.8.1. Многомерные массивы
- •5.9. Инициализация
- •5.9.1. Инициализация массивов
- •5.10. Приоритет и ассоциативность операторов
- •5.11. Порядок вычислений
- •5.12. Тип выражения
- •5.13. Приведение типов
- •5.13.1. Неявное приведение типов
- •5.13.2. Явное приведение и instanceof
- •5.13.3. Строковое приведение
- •5.14. Доступ к членам
- •5.15. Арифметические операторы
- •5.15.1. Целочисленная арифметика
- •5.15.2. Арифметика с плавающей точкой
- •5.15.3. Арифметика с плавающей точкой и стандарт ieee-754
- •5.15.4. Конкатенация строк
- •5.16. Операторы приращения и уменьшения
- •5.17. Операторы отношения и условный оператор
- •5.18. Поразрядные операции
- •5.19. Условный оператор
- •5.20. Операторы присваивания
- •5.21. Имена пакетов
- •Глава 6 порядок выполнения
- •6.1. Операторы и блоки
- •6.2. Оператор if-else
- •6.3. Оператор switch
- •6.4. Цикл while и do-while
- •6.5. Оператор for
- •6.6. Метки
- •6.7. Оператор break
- •6.8. Оператор continue
- •6.9. Оператор return
- •Глава 7 исключения
- •7.1. Создание новых типов исключений
- •7.2. Оператор throw
- •7.3. Условие throws
- •7.4. Операторы try, catch и finally
- •7.4.1. Условие finally
- •7.5. Когда применяются исключения
- •Глава 8 строки
- •8.1. Основные операции со строками
- •8.2. Сравнение строк
- •8.3. Вспомогательные методы
- •8.4. Создание производных строк
- •8.5. Преобразование строк
- •8.6. Строки и символьные массивы
- •8.7. Строки и массивы byte
- •8.8. Класс StringBuffer
- •8.8.1. Модификация буфера
- •8.8.2. Извлечение данных
- •8.8.3. Работа с емкостью буфера
- •Глава 9 потоки
- •9.1. Создание потоков
- •9.2. Синхронизация
- •9.2.1. Методы synchronized
- •9.2.2. Операторы synchronized
- •9.3. Методы wait и notify
- •9.4. Подробности, касающиеся wait и notify
- •9.5. Планирование потоков
- •9.6. Взаимная блокировка
- •9.7. Приостановка потоков
- •9.8. Прерывание потока
- •9.9. Завершение работы потока
- •9.10. Завершение приложения
- •9.11. Использование Runnable
- •9.12. Ключевое слово volatile
- •9.13. Безопасность потоков и ThreadGroup
- •9.14. Отладка потоков
- •Глава 10 пакеты
- •10.1. Имена пакетов
- •10.2. Пакетный доступ
- •10.3. Содержимое пакета
- •Глава 11 пакет ввода/вывода
- •11.1. Потоки
- •11.2. Класс InputStream
- •11.3. Класс OutputStream
- •11.4. Стандартные типы потоков
- •11.5. Фильтрующие потоки
- •11.6. Класс PrintStream
- •11.7. Буферизованные потоки
- •11.8. Байтовые потоки
- •11.9. Класс StringBufferInputStream
- •11.10. Файловые потоки и FileDescriptor
- •11.11. Конвейерные потоки
- •11.12. Класс Seq uenceInputStream
- •11.13. Класс LineNumberInputStream
- •11.14. Класс PushbackInputStream
- •11.15. Класс StreamTokenizer
- •11.16. Потоки данных
- •11.16.1. Классы потоков данных
- •11.17. Класс RandomAccessFile
- •11.18. Класс File
- •11.19. Интерфейс FilenameFilter
- •11.20. Классы ioException
- •Глава 12 стандартные вспомогательные средства
- •12.1. Класс BitSet
- •12.2. Интерфейс Enumeration
- •12.3. Реализация интерфейса Enumeration
- •12.4. Класс Vector
- •12.5. Класс Stack
- •12.6. Класс Dictionary
- •12.7. Класс Hashtable
- •12.8. Класс Properties
- •12.9. Классы Observer/Observable
- •12.10. Класс Date
- •12.11. Класс Random
- •12.12. Класс String Tokenizer
- •Глава 13 применение типов в программировании
- •13.1. Класс Class
- •13.2. Загрузка классов
- •13.3. Классы-оболочки: общий обзор
- •13.4. Класс Boolean
- •13.5. Класс Character
- •13.6. Класс Number
- •13.7. Класс Integer
- •13.8. Класс Long
- •13.9. Классы Float и Double
- •Глава 14 системное программирование
- •14.1. Стандартный поток ввода/вывода
- •14.2. Управление памятью
- •14.3. Системные свойства
- •14.4. Создание процессов
- •14.5. Класс Runtime
- •14.6. Разное
- •14.7. Безопасность
- •14.8. Класс Math
- •Приложение а Родные методы
- •А.1 Обзор
- •А.2.1 Имена
- •А.2.2 Методы
- •А.2.3 Типы
- •А.2.5 Средства безопасности
- •А.2.6 Работа с памятью
- •А.3 Пример
- •А.3.1 Внутреннее строение LockableFile
- •А.4 Строки
- •А.5 Массивы
- •А.6 Создание объектов
- •А.7 Вызов методов Java
- •А.8 Последнее предупреждение
- •Приложение б Runtime-исключения в Java
- •Б.1 Классы RuntimeException
- •Б.2 Классы Error
- •Приложение в Полезные таблицы
7.2. Оператор throw
Исключения возбуждаются оператором throw, которому в качестве параметра передается объект. Например, вот как выглядит реализация replaceValue в классе AttributedImpl из главы 4:
public void replaceValue(String name, Object newValue)
throws NoSuchAttributeException
{
Attr attr = find(name); // Искать attr
if (attr == null) // Если атрибут не найден
throw new NoSuchAttributeException(name, this);
attr.valueOf(newValue);
}
МетодreplaceValueсначалаищетимяатрибутавтекущемобъектеAttr.Если атрибут не найден, то возбуждается объект-исключение типа NoSuch AttribiteException и его конструктору предоставляются содержательные данные. Исключения являются объектами, поэтому перед использованием их необходимо создать. Если атрибут не существует, то его значение заменяется новым.
Разумеется, исключение может быть порождено вызовом метода, внутри которого оно возбуждается.
7.3. Условие throws
Первое, что бросается в глаза в приведенном выше методе replace Value,— это список проверяемых исключений, которые в нем возбуждаются. В Java необходимо перечислить проверяемые исключения, возбуждаемые методом, поскольку программист при вызове метода должен знать их в такой же степени, в какой он представляет себе нормальное поведение метода. Проверяемые исключения, возбуждаемые методом, не уступают по своей важности типу возвращаемого значения— и то и другое необходимо объявить.
Проверяемые исключения объявляются в условии throws, которое может содержать список значений, отделяемых друг от друга запятыми.
Внутри метода разрешается возбуждать исключения, являющиеся расширениями типа Exception в условии throws, поскольку всегда допускается полиморфно использовать класс вместо его суперкласса. Метод может возбуждать несколько различных исключений, являющихся расширениями одного конкретного класса, и при этом объявить в условии throws всего один суперкласс. Тем не менее, поступая таким образом, вы скрываете от работающих с методом программистов полезную информацию, потому что они не будут знать, какие из возможных расширенных типов исключений возбуждаются методом. В целях надлежащего документирования условие throws должно быть как можно более полным и подробным.
Контракт, определяемый условием throws, обязан неукоснительно соблюдаться— можно возбуждать лишь те исключения, которые указаны в данном условии. Возбуждение любого другого исключения (прямое, с помощью throw, или косвенное, через вызов другого метода) является недопустимым. Отсутствие условия throws не означает, что метод может возбуждать любые исключения; наоборот, оно говорит о том, что он не возбуждает никаких исключений.
Все стандартные исключения времени выполнения (такие, как ClassCast Exception и ArithmeticException) представляют собой расширения класса RuntimeException. О более серьезных ошибках сигнализируют исключения, которые являются расширениями класса Error и могут возникнуть в произвольный момент в произвольной точке программы. RuntimeException и Error— единственные исключения, которые не нужно перечислять в условии throws; они являются общепринятыми и могут возбуждаться в любом методе, поэтому компилятор не проверяет их. Полный список классов стандартных непроверяемых исключений приведен в Приложении Б.
Инициализаторы и блоки статической инициализации не могут возбуждать проверяемые исключения, как прямо, так и посредством вызова метода, возбуждающего исключение. Во время конструирования объекта нет никакого способа перехватить и обработать исключение. При инициализации полей выход заключается в том, чтобы инициализировать их внутри конструктора, который может возбуждать исключения. Для статических инициализаторов можно поместить инициализацию в статический блок, который бы перехватывал и обрабатывал исключение. Статические блоки не возбуждают исключений, но могут перехватывать их.
Java довольно строго подходит к обработке проверяемых исключений, поскольку это помогает избежать программных сбоев, вызванных невниманием к ошибкам. Опыт показывает, что программисты забывают про обработку ошибок или откладывают ее на будущее, которое так никогда и не наступает. Условие throws ясно показывает, какие исключения возбуждаются методом, и обеспечивает их обработку.
При вызове метода, у которого в условии throws приведено проверяемое исключение, имеются три варианта:
Перехватить исключение и обработать его.
Перехватить исключение и перенаправить его в обработчик одного из ваших исключений, для чего возбудить исключение типа, объявленного в вашем условии throws.
Объявить данное исключение в условии throws и отказаться от его обработки в вашем методе (хотя в нем может присутствовать условие finally, которое сначала выполнит некоторые завершающие действия; подробности приводятся ниже).
При любом из этих вариантов вам необходимо перехватить исключение, возбужденное другим методом; это станет темой следующего раздела.
Упражнение 7.1
Создайте класс-исключение ObjectNotFoundException для класса Linked List, построенного нами в предыдущих упражнениях. Включите в него метод find, предназначенный для поиска объектов в списке, который либо возвращает нужный объект LinkedList, либо возбуждает исключение, если объект отсутствует в списке. Почему такой вариант оказывается более предпочтительным, нежели возврат значения null для ненайденного объекта? Какие данные должны входить в ObjectNotFoundException?