- •Аннотация
- •Лекция 1. Что такое Java? История создания.
- •1. Что такое Java?
- •2. История создания Java
- •2.1. Сложности внутри Sun Microsystems
- •2.2. Проект Green
- •2.3. Компания FirstPerson
- •2.4. World Wide Web
- •2.5. Возрождение Oak
- •2.6. Java выходит в свет
- •3. История развития Java
- •3.1. Браузеры
- •3.2. Сетевые компьютеры
- •3.3. Платформа Java
- •4. Заключение
- •5. Контрольные вопросы
- •Аннотация
- •1. Основы объектно-ориентированного программирования
- •1.1. Методология процедурно-ориентированного программирования
- •1.2. Методология объектно-ориентированного программирования
- •1.3. Объекты
- •1.3.1. Состояние.
- •1.3.2. Поведение
- •1.3.3. Уникальность
- •1.4. Классы
- •1.4.1. Инкапсуляция
- •1.4.2. Полиморфизм
- •1.5. Типы отношений между классами
- •1.5.1. Агрегация
- •1.5.2. Ассоциация
- •1.5.3. Наследование
- •1.5.4. Метаклассы
- •1.6. Достоинства ООП
- •1.7. Недостатки ООП
- •1.8. Заключение
- •1.9. Контрольные вопросы
- •Аннотация
- •Лекция 3. Лексика языка
- •1. Лексика языка
- •1.1. Кодировка
- •1.2. Анализ программы
- •1.2.1. Пробелы
- •1.2.2. Комментарии
- •1.2.3. Лексемы
- •1.3. Виды лексем
- •1.3.1. Идентификаторы
- •1.3.2. Ключевые слова
- •1.3.3. Литералы
- •1.3.3.1. Целочисленные литералы
- •1.3.3.2. Дробные литералы
- •1.3.3.3. Логические литералы
- •1.3.3.4. Символьные литералы
- •1.3.3.5. Строковые литералы
- •1.3.3.6. Null литерал
- •1.3.3.7. Разделители
- •1.3.3.8. Операторы
- •1.3.3.9. Заключение
- •1.4. Дополнение: Работа с операторами
- •1.4.1. Операторы присваивания и сравнения
- •1.4.2. Арифметические операции
- •1.4.3. Логические операторы
- •1.4.4. Битовые операции
- •1.5. Заключение
- •1.6. Контрольные вопросы
- •Аннотация
- •Лекция 4. Типы данных
- •1. Введение
- •2. Переменные
- •3. Примитивные и ссылочные типы данных
- •3.1. Примитивные типы
- •3.2. Целочисленные типы
- •4. Дробные типы
- •5. Булевский тип
- •6. Ссылочные типы
- •6.1. Объекты и правила работы с ними
- •6.2. Класс Object
- •6.3. Класс String
- •6.4. Класс Class
- •7. Заключение
- •8. Заключение
- •9. Контрольные вопросы
- •Аннотация
- •Лекция 5. Имена. Пакеты
- •1. Введение
- •2. Имена
- •2.1. Простые и составные имена. Элементы.
- •2.2. Имена и идентификаторы
- •2.3. Область видимости (введение)
- •3. Пакеты
- •3.1. Элементы пакета
- •3.2. Платформенная поддержка пакетов
- •3.3. Модуль компиляции
- •3.3.1. Объявление пакета
- •3.3.2. Импорт-выражения
- •3.3.3. Объявление верхнего уровня
- •3.4. Уникальность имен пакетов
- •4. Область видимости имен
- •4.1. "Затеняющее" объявление (Shadowing)
- •4.2. "Заслоняющее" объявление (Obscuring)
- •5. Соглашения по именованию
- •6. Заключение
- •7. Контрольные вопросы
- •Аннотация
- •Лекция 6. Объявление классов
- •1. Введение
- •2. Модификаторы доступа
- •2.1. Предназначение модификаторов доступа
- •2.2. Разграничение доступа в Java
- •3. Объявление классов
- •3.1. Заголовок класса
- •3.2. Тело класса
- •3.3. Объявление полей
- •3.4. Объявление методов
- •3.5. Объявление конструкторов
- •3.6. Инициализаторы
- •4. Дополнительные свойства классов
- •4.1. Метод main
- •4.2. Параметры методов
- •4.3. Перегруженные методы
- •5. Заключение
- •6. Контрольные вопросы
- •Аннотация
- •Лекция 7. Преобразование типов
- •1. Введение
- •2. Виды приведений
- •2.1. Тождественное преобразование
- •2.2. Преобразование примитивных типов (расширение и сужение)
- •2.3. Преобразование ссылочных типов (расширение и сужение)
- •2.4. Преобразование к строке
- •2.5. Запрещенные преобразования
- •3. Применение приведений
- •3.1. Присвоение значений
- •3.2. Вызов метода
- •3.3. Явное приведение
- •3.4. Оператор конкатенации строк
- •3.5. Числовое расширение
- •3.5.1. Унарное числовое расширение
- •3.5.2. Бинарное числовое расширение
- •4. Тип переменной и тип ее значения
- •5. Заключение
- •6. Контрольные вопросы
- •Аннотация
- •1. Введение
- •2. Статические элементы
- •3. Ключевые слова this и super
- •4. Ключевое слово abstract
- •5. Интерфейсы
- •5.1. Объявление интерфейсов
- •5.2. Реализация интерфейса
- •5.3. Применение интерфейсов
- •6. Полиморфизм
- •6.1. Поля
- •6.2. Методы
- •6.3. Полиморфизм и объекты
- •7. Заключение
- •8. Контрольные вопросы
- •Аннотация
- •Лекция 9. Массивы
- •1. Введение
- •2. Массивы, как тип данных в Java
- •2.1. Объявление массивов
- •2.2. Инициализация массивов
- •2.3. Многомерные массивы
- •2.4. Класс массива
- •3. Преобразование типов для массивов
- •3.1. Ошибка ArrayStoreException
- •3.2. Переменные типа массив, и их значения
- •4. Клонирование
- •4.1. Клонирование массивов
- •5. Заключение
- •6. Контрольные вопросы
- •Аннотация
- •Лекция 10. Операторы и структура кода
- •1. Управление ходом программы
- •2. Нормальное и прерванное выполнение операторов
- •3. Блоки и локальные переменные
- •4. Пустой оператор
- •5. Метки
- •6. Оператор if
- •7. Оператор switch
- •8. Управление циклами
- •8.1. Цикл while
- •8.2. Цикл do
- •8.3. Цикл for
- •9. Операторы break и continue
- •9.1. Оператор continue
- •9.2. Оператор break
- •10. Именованные блоки
- •11. Оператор return
- •12. Оператор synchronized
- •13.1. Причины возникновения ошибок
- •13.2. Обработка исключительных ситуаций
- •13.2.1. Конструкция try-catch
- •13.2.2. Конструкция try-catch-finally
- •13.3. Использование оператора throw
- •13.4. Обрабатываемые и необрабатываемые исключения
- •13.5. Создание пользовательских классов исключений
- •13.6. Переопределение методов и исключения
- •13.7. Особые случаи
- •14. Заключение
- •15. Контрольные вопросы
- •Аннотация
- •Лекция 11. Пакет java.awt
- •1. Введение
- •2. Апплеты
- •2.1. Тег HTML <Applet>
- •2.2. Передача параметров
- •2.3. Контекст апплета
- •2.4. Отладочная печать
- •2.5. Порядок инициализации апплета
- •2.6. Перерисовка
- •2.7. Задание размеров графических изображений
- •2.8. Простые методы класса Graphics
- •2.9. Цвет
- •2.9.1. Методы класса Color
- •2.10. Шрифты
- •2.10.1. Использование шрифтов
- •2.10.2. Позиционирование и шрифты: FontMetrics
- •2.10.3. Использование FontMetrics
- •2.10.4. Центрирование текста
- •3. Базовые классы
- •4. Основные компоненты
- •5. Менеджеры компоновки
- •6. Окна
- •7. Меню
- •8. Обработка событий
- •8.1. Рисование "каракулей" в Java
- •8.2. Рисование "каракулей" с использованием встроенных классов
- •9. Заключение
- •10. Контрольные вопросы
- •Аннотация
- •Лекция 12. Потоки выполнения. Синхронизация
- •1. Введение
- •2. Многопоточная архитектура
- •3. Базовые классы для работы с потоками
- •3.1. Класс Thread
- •3.2. Интерфейс Runnable
- •3.3. Работа с приоритетами
- •3.4. Демон-потоки
- •4. Синхронизация
- •4.1. Хранение переменных в памяти
- •4.2. Модификатор volatile
- •4.3. Блокировки
- •5. Методы wait(), notify(), notifyAll() класса Object
- •6. Контрольные вопросы
- •Аннотация
- •Лекция 13. Пакет java.lang.
- •1. Введение
- •2. Object
- •3. Class
- •4. Wrapper Classes
- •4.1. Integer
- •4.2. Character
- •4.3. Boolean
- •4.4. Void
- •5. Math
- •6. Строки
- •6.1. String
- •6.2. StringBuffer
- •7. Системные классы
- •7.1. ClassLoader
- •7.2. SecurityManager - менеджер безопасности
- •7.3. System
- •7.4. Runtime
- •7.5. Process
- •8. Потоки исполнения
- •8.1. Runnable
- •8.2. Thread
- •8.3. ThreadGroup
- •9. Исключения
- •10. Заключение
- •11. Контрольные вопросы
- •Аннотация
- •Лекция 14. Пакет java.util
- •1. Введение
- •2. Работа с датами и временем
- •2.1. Класс Date
- •2.2. Классы Calendar и GregorianCalendar
- •2.3. Класс TimeZone
- •2.4. Класс SimpleTimeZone
- •3. Интерфейс Observer и класс Observable
- •4. Коллекции
- •4.1. Интерфейсы
- •4.1.1. Интерфейс Collection
- •4.1.2. Интерфейс Set
- •4.1.3. Интерфейс List
- •4.1.4. Интерфейс Map
- •4.1.5. Интерфейс SortedSet
- •4.1.6. Интерфейс SortedMap
- •4.1.7. Интерфейс Iterator
- •4.2. Aбстрактные классы используемые при работе с коллекциями.
- •4.3. Конкретные классы коллекций
- •4.4. Класс Collections
- •5. Класс Properties
- •6. Интерфейс Comparator
- •7. Класс Arrays
- •8. Класс StringTokenizer
- •9. Класс BitSet
- •10. Класс Random
- •11. Локализация
- •11.1. Класс Locale
- •11.2. Класс ResourceBundle
- •12. Заключение
- •13. Контрольные вопросы
- •Аннотация
- •Лекция 15. Пакет java.io
- •1. Система ввода/вывода. Потоки данных (stream)
- •1.1. Классы InputStream и OutputStream
- •1.2. Классы-реализации потоков данных
- •1.2.1. Классы ByteArrayInputStream и ByteArrayOutputStream
- •1.2.2. Классы FileInputStream и FileOutputStream
- •1.2.3. PipedInputStream и PipedOutputStream
- •1.2.4. StringBufferInputStream
- •1.2.5. SequenceInputStream
- •1.3. Классы FilterInputStreeam и FilterOutputStream. Их наследники.
- •1.3.1. BufferedInputStream и BufferedOutputStream
- •1.3.2. LineNumberInputStream
- •1.3.3. PushBackInputStream
- •1.3.4. PrintStream
- •1.3.5. DataInputStream и DataOutputStream
- •2. Serialization
- •2.1. Версии классов
- •3. Классы Reader и Writer. Их наследники.
- •4. Класс StreamTokenizer
- •5. Работа с файловой системой.
- •5.1. Класс File
- •5.2. Класс RandomAccessFile
- •6. Заключение
- •7. Контрольные вопросы
- •Аннотация
- •Лекция 16. Введение в сетевые протоколы
- •1. Основы модели OSI
- •2. Physical layer (layer 1)
- •3. Data layer (layer 2)
- •3.1. LLC sublayer.
- •3.2. MAC sublayer.
- •4. Network layer (layer 3)
- •4.1. Class A
- •4.2. Class B
- •4.3. Class CClass DClass E
- •5. Transport layer (layer 4)
- •6. Session layer (layer 5)
- •7. Presentation layer (layer 6)
- •8. Application layer (layer 7)
- •9. Утилиты для работы с сетью
- •9.1. IPCONFIG (IFCONFIG)
- •9.3. Ping
- •9.4. Traceroute
- •9.5. Route
- •9.6. Netstat
- •9.7. Задания для практического занятия
- •10. Пакет java.net
- •11. Заключение
- •12. Контрольные вопросы
Классы FilterInputStreeam и FilterOutputStream. Их наследники. |
Стр. 11 из 34 |
Vector vector = new Vector();
vector.add(new StringBufferInputStream("Begin file1\n")); vector.add(new FileInputStream("file1.txt"));
vector.add(new StringBufferInputStream("\nEnd of file1, begin file2\n")); vector.add(new FileInputStream("file2.txt"));
vector.add(new StringBufferInputStream("\nEnd of file2")); Enumeration enum = vector.elements();
sequenceStream = new SequenceInputStream(enum);
Если заменить в предыдущем примере инициализацию sequenceeStream на приведенную здесь, то в файл file3.txt кроме содержимого файлов file1.txt и file2.txt будут записаны еще и три строки - одна в начале файла, одна между содержимым файлов file1.txt и file2.txt и еще одна дописана в конец file3.txt.
1.3. Классы FilterInputStreeam и FilterOutputStream. Их наследники.
Задачи, возникающие при вводе/выводе крайне разнообразны - этот может быть считывание байтов из файлов, объектов из файлов, объектов из массивов, буферизованное считывание строк из массивов. В такой ситуации решение путем простого наследования приводит к возникновению слишком большого числа подклассов. Решение же, когда требуется совмещение нескольких свойств, высокоэффективно в виде надстроек. (В ООП этот паттерн называется адаптер.) Надстройки - наложение дополнительных объектов для получения новых свойств и функций. Таким образом, необходимо создать несколько дополнительных объектов - адаптеров к классам ввода/вывода. В java.io их еще называют фильтрами. При этом надстройка-фильтр, включает в себя интерфейс объекта, на который надстраивается, и поэтому может быть в свою очередь дополнительно быть надстроена.
В java.io интерфейс для таких надстроек ввода/вывода предоставляют классы FilterInputStream (для входных потоков) и FilterOutputStream (для выходных потоков). Эти классы унаследованы от основных базовых классов ввода/вывода - InputStream и OutputStream соответственно. Конструкторы этих классов принимают в качестве параметра объект InputStream и имеют модификатор доступа protected. Сами же эти классы являются базовыми для надстроек. Поэтому только наследники могут вызывать его(при их создании), передавая переданный им поток. Таким образом обеспечивается некоторый общий интерфейс для надстраиваемых объектов.
Надстройки можно попробовать разделить на два основных типа - одни меняют данные, с которыми может работать поток, другие меняют внутренние механизмы потока: производят буферизацию, позволяют вернуть в поток считанные байты, или же посчитать количество считанных строк.
1.3.1. BufferedInputStream и BufferedOutputStream
На практике, при считывании с внешних устройств, ввод данных почти всегда необходимо буферизировать. Для буферизации данных и служат классы BuffereInputStream и BufferedOutputStream.
BufferedInputStream - содержит в себе массив байт, который служит буфером для считываемых данных. То есть, когда байты из потока считываются (вызов метода read()) либо пропускаются(метод skip()), сначала перезаписывается этот буферный массив, при
Программирование на Java
Rendered by www.RenderX.com
Стр. 12 из 34 |
Система ввода/вывода. Потоки данных (stream) |
этом считываются сразу много байт за раз. Так же класс BufferedInputStream добавляет поддержку методов mark() и reset(). Эти методы определены еще в классе InputStream, но их реализация по умолчанию бросает исключение IOException. Метод mark() запоминает точку во входном потоке и метод reset() приводит к тому, что все байты, считанные после наиболее позднего вызова метода mark(), будут считаны заново, прежде чем новые байты будут считываться из содержащегося входного потока.
BufferedOutputStream - при использовании объекта этого класса, запись производится без необходимости обращения к устройству ввода/вывода при записи каждого байта. Сначала данные записываются во внутренний буфер. Непосредственное обращение к устройству вывода и, соответственно, запись в него произойдет, когда буфер будет полностью заполнен. Освобождение буфера с записью байт на устройство вывода можно обеспечить и непосредственно - вызовом метода flush(). Так же буфер будет освобожден непосредственно перед закрытием потока (вызов метода close()). При вызове этого метода также будет закрыт и поток, над которым буфер надстроен.
Следующий пример наглядно демонстрирует повышение скорости считывания данных из файла с использованием буфера.
try {
String fileName = "d:\\file1"; InputStream inStream = null; OutputStream outStream = null;
//Записать в файл некоторое количество байт long timeStart = System.currentTimeMillis(); outStream = new FileOutputStream(fileName); outStream = new BufferedOutputStream(outStream); for(int i=1000000; --i>=0;){ outStream.write(i);
}
long time = System.currentTimeMillis() - timeStart; System.out.println("Writing durates: " + time + " millisec"); outStream.close();
// Определить время считывания без буферизации timeStart = System.currentTimeMillis(); inStream = new FileInputStream(fileName); while(inStream.read()!=-1){
}
time = System.currentTimeMillis() - timeStart; inStream.close();
System.out.println("Direct read durates " + (time) + " millisec"); timeStart = System.currentTimeMillis();
inStream = new FileInputStream(fileName); inStream = new BufferedInputStream(inStream); while(inStream.read()!=-1){
}
time = System.currentTimeMillis() - timeStart; inStream.close();
System.out.println("Buffered read durates " + (time) + " millisec");
Программирование на Java
Rendered by www.RenderX.com
Классы FilterInputStreeam и FilterOutputStream. Их наследники. |
Стр. 13 из 34 |
} catch (IOException e) { pr("IOException: " + e.toString()); e.printStackTrace();
}
Результатом могут быть, например, такие значения:
Writing durates: 359 millisec
Direct read durates 6546 millisec
Buffered read durates 250 millisec
В данном случае не производилось никаких дополнительных вычислений, занимающих процессорное время, только запись и считывание из файла. При этом считывание с использованием буфера заняло в 10 (!) раз меньше времени, чем аналогичное без буферизации. Для более быстрого выполнения программы запись файл производилась с буферизацией, однако ее влияние на скорость записи нетрудно проверить, убрав из программы строку, создающую BufferedOutputStream. Оставляем это для самостоятельной проверки.
Классы BufferedInputStream и BufferedOutputStream добавляют только внутреннюю логику по обработке запросов, они не добавляют никаких дополнительных методов. Следующие два фильтра как раз добавляют некоторые дополнительные возможности при работе с потоками. Однако, первый из них - LineNumberInputStream объявлен deprecated начиная с версии jdk 1.1, и использовать его не рекомендуется.
1.3.2. LineNumberInputStream
Расширяет функциональность InputStream тем, что дополнительно производит подсчет, сколько строк было считано из потока. Номер строки, на которой в данный момент происходит чтение можно узнать вызовом метода getLineNumber(). Так же можно и пеерейти к определенной строке, вызовом метода setLineNumber(int lineNumber).
Под строкой при этом понимается набор байт, оканчивающийся либо '\n' либо '\r' либо их комбинацией '\r\n' именно в этой последовательности. Аналогичный класс для OutputFilter - отсутствует.
1.3.3. PushBackInputStream
Этот фильтр позволяет вернуть во входной поток считанные из него данные. Это действие производится вызовом метода unread(). Понятно, что обеспечивается такая функциональность за счет наличия в классе некоторого буфера - массива байт, который заполняется при считывании из потока. Если будет произведен откат, то потом просто эти данные будут выдаваться еще раз, как будто только были считаны. При конструировании можно указать максимальное количество байт, которое может быть возвращено в поток. Аналогичный класс для OutputFilter - отсутствует.
Следующий класс также является deprecated, и его не рекомендуется применять при написании программ, работающих с различными кодировками. Однако он продолжает активно использоваться в силу исторических причин, так как статические поля out и err класса System ссылаются на объекты именно этого класса, и, поэтому его необходимо знать.
Программирование на Java
Rendered by www.RenderX.com
Стр. 14 из 34 |
Система ввода/вывода. Потоки данных (stream) |
1.3.4. PrintStream
Используется для конвертации и записи строк в байтовый поток. В классе PrintStream определен метод print(), принимающий различные примитивные типы java а так же Object. При вызове этих методов передаваемые данные будут сначала превращены в строку вызовом метода String.valueOf(), после чего записаны в поток. То есть, в поток данные будут записаны в представлении, удобном для прочтения человеком. При этом, даже если возникает исключение, то оно обрабатывается внутри метода print и дальше НЕ кидается. При записи строки используется кодировка, определяемая из настроек системы, где выполняется программа. При этом PrintStream не поддерживает Unicode. Вообще же для работы с текстовыми данными следует использовать Writer`ы. Аналогичный класс для
InputFilter - отсутствует.
Итак, ряд классов-потоков уже устарел и не рекомендуется к применению. Тем не менее они были описаны в основном для справочного материала и полноты картины. Действительный интерес и практические выгоды от использования предоставляет следующая пара классов.
1.3.5. DataInputStream и DataOutputStream
До сих пор речь шла только о считывании и записи в поток данных в виде byte. Для работы с другими примитивными типами данных java, определены интерфейсы DataInput и DataOutput, и существующие их реализации - классы-фильтры DataInputStream и DataOutputStream. Их место в иерархии классов ввода/вывода можно увидеть на диаграммах классов, приведенных на рис.1 и рис.2.
Интерфейсы DataInput и DataOutput определяют, а классы DataInputStream и DataOutputStream, соответственно реализуют, методы считывания и записи всех примитивных типов данных. При этом происходит конвертация этих данных в byte и обратно. При этом в поток будут записаны байты, а ответственность за восстановление данных лежит только на разработчике - нужно считывать данные в виде тех же типов, в той же последовательности, как и производилась запись. То есть, можно, конечно, записать несколько раз int или long, а потом считывать их как short или что-нибудь еще - считывание произойдет корректно и никаких предупреждений о возникшей ошибке не возникнет, но результат будет соответствующий - значения, которые никогда не записывались. Это наглядно показано в следующем примере:
try {
ByteArrayOutputStream out = new ByteArrayOutputStream(); DataOutputStream outData = new DataOutputStream(out); outData.writeByte(128); // it would write -128, as casted to byte outData.writeInt(128);
outData.writeLong(128);
outData.writeDouble(128);
outData.close();
byte[] bytes = out.toByteArray();
InputStream in = new ByteArrayInputStream(bytes); DataInputStream inData = new DataInputStream(in); System.out.println("Read data in order it was writen: "); System.out.println("readByte: " + inData.readByte());
Программирование на Java
Rendered by www.RenderX.com