- •Кен Арнольд Джеймс Гослинг Дэвид Холмс Язык программирования 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
 - •Приложение в Полезные таблицы
 
11.5. Фильтрующие потоки
Фильтрующие потоки добавляют несколько новых конструкторов к базовым конструкторам классов InputStream и OutputStream. Им передается поток соответствующего типа (входной или выходной), с которым необходимо соединить объект. Фильтрующие потоки позволяют объединять потоки в “цепочки” и тем самым создавать составной поток с большими возможностями. Приведенная программа печатает номер строки файла, в которой будет обнаружено первое вхождение заданного символа:
import java.io.*;
class FindChar {
public static void main (String[] args)
throws Exception
{
if (args.length != 2)
throw new Exception("need char and file");
int match = args[0].charAt(0);
FileInputStream
fileIn = new FileInputStream(filein);
int ch;
while ((ch == in.read()) != -1) {
if (ch == match) {
System.out.println("'" + (char)ch +
"' at line " + in.getLineNumber());
System.exit(0);
}
}
System.out.println(ch + " not found");
System.exit(1);
}
}
Программа создает поток класса FileInputStream с именем fileIn для чтения из указанного файла и затем вставляет перед ним объект класса LineNumberInputStream с именем in. Объекты LineNumberInputStream получают ввод от входных потоков, за которыми они закреплены, и следят за нумерацией строк. При чтении байтов из in на самом деле происходит чтение из потока fileIn, который получает эти байты из входного файла. Если запустить программу с файлом ее собственного исходного текста и буквой ‘I’ в качестве аргументов, то результат работы будет выглядеть следующим образом:
‘I’ at line 10
Вы можете “сцепить” произвольное количество объектов FilterInput Stream. В качестве исходного источника байтов допускается произвольный объект InputStream, не обязательно относящийся к классу FilterInput Stream. Возможность сцепления является одним из основных достоинств фильтрующих потоков, причем самый первый поток в цепочке не должен относиться к классу FilterInputStream.
Объекты FilterOutputStream могут сцепляться аналогичным образом. При этом байты, записанные в один выходной поток, будут подвергаться фильтрации и записываться в другой выходной поток. Все потоки, от первого до предпоследнего, должны относиться к классу FilterOutputStream, но последний поток может представлять собой любую из разновидностей Output Stream.
Применение фильтрующих потоков позволяет усовершенствовать поведение стандартных потоков. Например, чтобы всегда знать номер текущей строки в System.in, можно вставить в начало программы следующий фрагмент:
LineNumberInputStream
lnum = new LinenumberInputStream(System.in);
System.in = lnum;
Во всем остальном тексте программы производятся обычные операции с System.in, однако теперь появляется возможность следить за нумерацией строк. Для этого используется следующий вызов:
lnum.getLineNumber();
Поток LineNumberInputStream, закрепленный за другим потоком Input Stream, следует контракту последнего, если InputStream— единственный тип, к которому мог бы относиться данный поток. System.in может быть отнесен только к типу InputStream, так что весь код программы, в котором он используется, вправе рассчитывать только на выполнение контракта этого типа. LineNu m berInputStream поддерживает более широкий спектр функций, так что замена исходного объекта на тот же самый объект с добавленными функциями нумерации строк оказывается вполне допустимой.
Упражнение 11.2
Расширьте FilterInputStream для создания класса, который осуществляет построчное чтение и возврат данных, с использованием метода, блокирующего работу программы до появления полной строки ввода.
Упражнение 11.3
Расширьте FilterOutputStream для создания класса, который преобразует каждое слово входного потока в заглавный регистр (title case). /См. раздел 13.5 - Примеч. перев/
Упражнение 11.4
Создайте пару фильтрующих потоковых классов для работы со сжатыми в произвольном формате данными; при этом поток CompressInputStream должен уметь расшифровывать данные, созданные потоком Compress OutputStream.
