В. Монахов
3-е издание
Санкт-Петербург
«БХВ-Петербург»
2011
УДК 681.3.068
ББК 32.973.26-018.1
М77
Монахов В. В.
М77 Язык программирования Java и среда NetBeans. — 3-е изд., перераб.
и доп. — СПб.: БХВ-Петербург, 2011. — 704 с.: ил. + DVD
ISBN 978-5-9775-0671-7
Книга написана на базе курса лекций, читаемых автором на кафедре вычислительной физики Санкт-Петербургского государственного университета. Изложены основные синтаксические конструкции Java, принципы объектно-ориентированного программирования, особенности проведения численных расчетов. Приводятся сведения о среде NetBeans, предназначенной для профессиональной разработки всех видов программного обеспечения Java (ME, SE и EE). Рассказывается о создании сетевых приложений и приложений для мобильных устройств. Разбираются методики написания многопоточных приложений Java для систем с многоядерными процессорами. Материал сопровождается большим количеством примеров.
В третьем издании внесены исправления и на DVD добавлены новые примеры и дистрибутив NetBeans 6.9.1. Также на DVD расположены дистрибутивы JDK 6u и NetBeans 6.5 для Windows и Linux.
Для начинающих Java-программистов и студентов УДК 681.3. ББК 32.973.26-018. Группа подготовки издания:
Екатерина Кондукова Главный редактор Игорь Шишигин Зам. главного редактора Григорий Добин Зав. редакцией Леонид Кочин Редактор Ольги Сергиенко Компьютерная верстка Зинаида Дмитриева Корректор Елены Беляевой Оформление обложки Николай Тверских Зав. производством Лицензия ИД № 02429 от 24.07.00. Подписано в печать 30.12.10.
Формат 70 1001/16. Печать офсетная. Усл. печ. л. 56,76.
Тираж 1500 экз. Заказ № "БХВ-Петербург", 190005, Санкт-Петербург, Измайловский пр., 29.
Санитарно-эпидемиологическое заключение на продукцию № 77.99.60.953.Д.005770.05.09 от 26.05.2009 г. выдано Федеральной службой по надзору в сфере защиты прав потребителей и благополучия человека.
Отпечатано с готовых диапозитивов в ГУП "Типография "Наука" 199034, Санкт-Петербург, 9 линия, ISBN 978-5-9775-0671-7 © Монахов В. В., © Оформление, издательство "БХВ-Петербург", Оглавление Предисловие к третьему изданию
Введение
Глава 1. Общие представления о языке Java
1.1. Java и другие языки программирования. Системное и прикладное программирование
1.2. Виртуальная Java-машина, байт-код, JIT-компиляция. Категории программ, написанных на языке Java
1.3. Алфавит языка Java. Десятичные и шестнадцатеричные цифры и целые числа.
Зарезервированные слова
Алфавит языка Java
Десятичные и шестнадцатеричные цифры и целые числа
Зарезервированные слова и литералы языка Java
1.4. Управляющие последовательности. Символы Unicode. Специальные символы............. Управляющие последовательности
Управляющие последовательности — символы формирования текста
Управляющие последовательности — символы Unicode
Простые специальные символы
Составные специальные символы
1.5. Идентификаторы. Переменные и типы. Примитивные и ссылочные типы
1.6. Процедурное и объектно-ориентированное программирование. Инкапсуляция............. 1.7. Работа со ссылочными переменными. Сборка мусора
1.8. Проекты. Пакеты. Уровни видимости классов. Импорт классов
1.9. Базовые пакеты и классы Java
1.10. Технологии Java,.NET, ASP, PHP
1.11. Среды разработки NetBeans, Eclipse, JDeveloper, JBuilder, IntelliJ IDEA
NetBeans 6.5
Eclipse 3.4.1 (Ganimede)
JDeveloper 11
JBuilder 2008
IntelliJ IDEA 7.0.4
Общий итог сравнения сред разработки
Краткие итоги по главе
Типичные ошибки
Задания
Глава 2. Среда NetBeans 6.5
2.1. Установка JDK 6
2.2. Установка среды NetBeans 6.5
2.3. Создание в NetBeans простейшего приложения Java
2.4. Компиляция файлов проекта и запуск приложения. Jar-файлы
2.5. Структура проекта NetBeans
2.6. Создание в NetBeans приложения Java с графическим интерфейсом
2.7. Редактор экранных форм
2.8. Свойства компонентов
2.9. Внешний вид приложения — технология Look and Feel
2.10. Ведение проектов
2.11. Редактирование меню экранной формы
2.12. Создание нового класса
2.13. Документирование исходного кода в Java
2.14. Основные компоненты пакетов swing и awt
2.15. Менеджеры размещения (Layout) и якоря (Anchor)
2.16. Создание приложения Desktop Application
Краткие итоги по главе
Типичные ошибки
Задания
Глава 3. Примитивные типы данных и операторы для работы с ними.......... 3.1. Булевый (логический) тип
3.2. Целые типы, переменные, константы
3.3. Основные операторы для работы с целочисленными величинами
3.4. Вещественные типы и класс Math
3.5. Правила явного и автоматического преобразования типа при работе с числовыми величинами
3.6. Оболочечные классы. Упаковка (boxing) и распаковка (unboxing)
3.7. Приоритет операторов
Краткие итоги по главе
Типичные ошибки
Задания
Глава 4. Работа с числами в языке Java
4.1. Двоичное представление целых чисел
Позиционные и непозиционные системы счисления
Двоичное представление положительных целых чисел
Двоичное представление отрицательных целых чисел. Дополнительный код.............. Сложение положительного и отрицательного чисел
Сложение отрицательных чисел
Проблемы целочисленной машинной арифметики. Целочисленное переполнение...... Сложение положительных чисел
Умножение положительных чисел
Шестнадцатеричное представление целых чисел и перевод из одной системы счисления в другую
Преобразование чисел из системы с меньшим основанием в систему с большим основанием
Преобразование чисел из системы с большим основанием в систему с меньшим основанием
Преобразование чисел в системах счисления с кратными основаниями................. 4.2. Побитовые маски и сдвиги
4.3. Двоичное представление вещественных чисел
Двоичные дроби
Мантисса и порядок числа
Научная нотация записи вещественных чисел
Стандарт IEEE 754 представления чисел в формате с плавающей точкой
Краткие итоги по главе
Типичные ошибки
Задания
Глава 5. Управляющие конструкции
5.1. Составной оператор
5.2. Условный оператор if
5.3. Оператор выбора switch
5.4. Условное выражение...?... :...
5.5. Операторы инкремента ++ и декремента --
5.6. Оператор цикла for
5.7. Ошибки при использовании вещественного счетчика цикла
5.8. Эффективная организация циклов при вычислениях в формате с плавающей точкой
5.9. Особенности целочисленных вычислений — организация циклов, приоритет операторов и арифметическое переполнение
5.10. Оператор цикла while — цикл с предусловием
5.11. Оператор цикла do...while — цикл с постусловием
5.12. Операторы прерывания continue, break, return, System.exit
Краткие итоги по главе
Типичные ошибки
Задания
Глава 6. Начальные сведения об объектном программировании
6.1. Наследование и полиморфизм
6.2. Функции. Модификаторы. Передача примитивных типов в функции
6.3. Локальные и глобальные переменные. Модификаторы доступа и правила видимости. Ссылка this
6.4. Передача ссылочных типов в функции. Проблема изменения ссылки внутри подпрограммы
6.5. Наследование. Суперклассы и подклассы. Переопределение методов
6.6. Наследование и правила видимости. Зарезервированное слово super
6.7. Статическое и динамическое связывание методов. Полиморфизм
6.8. Базовый класс Object
6.9. Конструкторы. Зарезервированные слова super и this. Блоки инициализации............... 6.10. Удаление неиспользуемых объектов и метод finalize. Проблема деструкторов для сложно устроенных объектов
6.11. Перегрузка методов
6.12. Правила совместимости ссылочных типов как основа использования полиморфного кода. Приведение и проверка типов
Краткие итоги по главе
Типичные ошибки
Задания
Глава 7. UML-диаграммы. Прямое и обратное проектирование.
Рефакторинг
7.1. UML-диаграммы
7.2. Структура окон проектов с UML-диаграммами
7.3. Панель инструментов проектов с UML-диаграммами
7.4. Прямое проектирование (Forward engineering) — построение кода классов по UMLдиаграммам
7.5. Обратное проектирование (Reverse engineering) — построение UML-диаграмм по разработанным классам
7.6. Рефакторинг
Первый случай — переименование элементов программы
Второй случай — перемещение класса
Третий случай — копирование класса для его дальнейшей модификации
Четвертый случай — безопасное удаление элемента программы
Пятый случай — изменение списка параметров метода
Шестой случай — инкапсуляция полей данных
Краткие итоги по главе
Типичные ошибки
Задания
Глава 8. Важнейшие объектные типы
8.1. Массивы
8.2. Коллекции, списки, итераторы
8.3. Перебор в цикле элементов коллекций. Оператор цикла for-each
8.4. Работа со строками в Java. Строки как объекты. Классы String, StringBuffer и StringBuilder
8.5. Типы-перечисления (enum)
8.6. Работа с датами и временем. Класс GregorianCalendar
8.7. Работа с графикой и графическим пользовательским интерфейсом
Код визуализации и код бизнес-логики приложения
Графические примитивы
Пример метода, работающего с графикой
8.8. Исключительные ситуации
Обработка исключительных ситуаций
Иерархия исключительных ситуаций
Объявление типа исключительной ситуации и оператор throw
Объявление метода, который может возбуждать исключительную ситуацию.
Зарезервированное слово throws
8.9. Работа с файлами и папками
Работа с файлами и папками с помощью объектов типа File
Выбор файлов и папок с помощью файлового диалога
Работа с потоками ввода/вывода
Краткие итоги по главе
Типичные ошибки
Задания
Глава 9. Интерфейсы и композиция
9.1. Проблемы множественного наследования классов. Интерфейсы
9.2. Отличия интерфейсов от классов. Проблемы наследования интерфейсов
9.3. Пример работы с интерфейсами
9.4. Композиция — еще одна альтернатива множественному наследованию
Краткие итоги по главе
Типичные ошибки
Задания
Глава 10. Многопоточное программирование и многоядерные системы....... 10.1. Потоки выполнения (threads) и синхронизация
10.2. Преимущества и проблемы при работе с потоками выполнения
10.3. Синхронизация по ресурсам и событиям
Синхронизация по ресурсам
Синхронизация по событиям
10.4. Класс Thread и интерфейсы Runnable и Callable. Создание и запуск потока выполнения
10.5. Поля и методы, заданные в классе Thread
10.6. Работа многопоточных приложений в многопроцессорных и многоядерных системах
Причины перехода к многопроцессорным и многоядерным системам
Пример многопоточной программы
Работа многопоточного приложения на многоядерном компьютере
10.7. Синхронизация на основе интерфейсов Lock и Condition
Интерфейс Lock
Интерфейс Condition
Краткие итоги по главе
Типичные ошибки
Задания
Глава 11. Введение в сетевое программирование
11.1. Краткая справка по языку HTML
Система WWW и язык HTML
Теги и их атрибуты
Математические и специальные символы, греческие буквы
11.2. Апплеты
Структура апплета
Примеры апплетов. Аннотация @Override
Создание проекта с апплетами
Редактор HTML-документов, стилей CSS и кода JavaScript
11.3. Сервлеты
Создание сервлета и конфигурирование сервера приложений
Локализация сервлетов — работа с языковыми форматами
11.4. Технология JSP — Java Server Pages
11.5. Технология JSTL — JSP Standard Tag Library
Краткие итоги по главе
Типичные ошибки
Задания
Глава 12. Вложенные классы
12.1. Виды вложенных классов
12.2. Статические (static) вложенные классы и интерфейсы
12.3. Внутренние (inner) классы
12.4. Локальные (local) классы
12.5. Анонимные (anonimous) классы и обработчики событий
12.6. Анонимные (anonimous) классы и слушатели событий (listeners)
Краткие итоги по главе
Типичные ошибки
Задания
Глава 13. Приложение с графическим интерфейсом — DesktopApplication.... 13.1. Структура простой заготовки DesktopApplication
13.2. Исходный код класса DesktopApplication
13.3. Исходный код класса DesktopApplicationView
13.4. Конструктор главной формы приложения. Ресурсы приложения и концепция управляющих синглетонов
13.5. Аннотация @Action и показ справки
13.6. Концепция управляющего объекта-модели. Модель TaskMonitor, класс Task и обработчик propertyChange
13.7. Создание задачи типа Task. Назначение иконок и добавление изображений............... 13.8. Локализация приложения
13.9. Измерение времени и досрочное прекращение выполнения задания
13.10. Работа с межпрограммным буфером обмена — Сlipboard
Копирование строк и изображений из буфера обмена в программу
Копирование строк из программы в буфер обмена. Класс StringSelection
Копирование изображений из программы в буфер обмена. Создание класса ImageSelection
13.11. Многопоточная система вычислений и индикации
Краткие итоги по главе
Типичные ошибки
Задания
Глава 14. Программирование мобильных телефонов
14.1. Спецификация Java Micro Edition. Конфигурации и профили. Мидлеты
14.2. Создание приложений для мобильных устройств
14.3. Дизайнер пользовательского интерфейса мидлета
14.4. Исходный код мидлета Hello, World!
14.5. Заготовка мидлета "Крестики-нолики"
14.6. Код бизнес-логики мидлета
14.7. Создание собственного компонента, являющегося наследником TableItem, и мидлета на его основе. Создание библиотеки
14.8. Запуск мидлета "Крестики-нолики" на реальном телефоне
14.9. Пример мидлета с переключением экрана и списком выбора
14.10. Примеры приложений для мобильных телефонов, поставляемые со средой NetBeans
Краткие итоги по главе
Типичные ошибки
Задания
Глава 15. Компонентное программирование
15.1. Компонентная архитектура JavaBeans
15.2. Создание компонента в NetBeans 6.5
15.3. Пример создания компонента в NetBeans 6.5 — панель с заголовком
15.4. Добавление в компонент новых свойств
15.5. Добавление в компонент новых событий
Краткие итоги по главе
Типичные ошибки
Задания
Глава 16. Платформо-зависимые методы и модуль C/C++ Pack
16.1. Использование динамических библиотек. Объявление платформо-зависимых (native) методов
16.2. Интерфейс JNI (Java Native Interface) взаимодействия Java с C/C++.
Соответствие типов Java и C++
16.3. Пакет C/C++ Pack. Подключение компиляторов C++, C и библиотек
16.4. Создание приложений C++ и C
16.5. Примеры приложений с native-методами
Первый этап. Создание исходного кода Java для native-методов
Второй этап. Генерация h-файла заголовка C++, содержащего декларацию методов.... Третий этап. Написание на C++ реализации методов, заголовки которых заданы в сгенерированном файле jnipackage_JniMultiply.h
Четвертый этап. Компиляция кода C++ в динамическую библиотеку (DLL)............. Пятый этап. Запуск приложения вместе с DLL в NetBeans
Шестой этап. Распространение приложения вместе с DLL
Краткие итоги по главе
Типичные ошибки
Задания
Глава 17. Отладка, тестирование и профилирование программ
17.1. Отладка приложений в среде NetBeans
17.2. Команды режима пошагового выполнения
17.3. Пример отладки неправильно работающего приложения
17.4. Принцип "презумпции виновности" и тестирование классов
17.5. Профилирование приложений
17.6. Профилирование отдельных методов
17.7. Настройка профилировщика "на лету". Точки профилирования
17.8. Нахождение проблем с использованием памяти — телеметрия
17.9. Профилирование использования памяти классами
Краткие итоги по главе
Типичные ошибки
Задания
Заключение
Приложение. Описание прилагаемого DVD
Литература
Основная
Дополнительная
Предметный указатель
10 Оглавление Предисловие к третьему изданию Год, прошедший со времени выхода второго издания, оказался богат на события в мире Java и NetBeans. Во-первых, состоялся выход большого количества обновлений дистрибутивов Java. Во-вторых, появились версии среды NetBeans 6.7, 6.8 и 6.9.
В-третьих, вышел дистрибутив Open JDK (см. http://www.openjdk.org/), позволивший гарантировать дальнейшее существование платформы Java и основанных на ней технологий независимо от судьбы корпорации Sun Microsystems. И, кроме того, корпорация Oracle, один из мировых лидеров в области индустрии программного обеспечения, приобрела фирму Sun Microsystems.
Предыдущее издание заняло достойное место среди компьютерной литературы по программированию на языке Java для начинающих. Ведь другие учебники на русском языке, в которых изложение материала основано на использовании современных сред разработки, просто-напросто отсутствуют, а учиться современному программированию с помощью морально устаревших технологий — не самый лучший выбор. Третье издание является исправленной версией предыдущего, с коррекцией найденных опечаток и мелких ошибок, а также с новыми дистрибутивами Java и NetBeans.
К книге приложен DVD с материалами, соответствующими ее тексту (примерами, а также дистрибутивами Java JDK 6u11 и NetBeans 6.5), для того чтобы желающие могли проделать все ровно так, как описано в тексте глав. Тем не менее, на DVD имеются и более современные дистрибутивы: текущие на момент верстки третьего издания версии JDK 6u22 и NetBeans 6.9.1 в вариантах для Windows и Linux. Автор рекомендует в любом случае устанавливать более новую версию JDK 6u22. Примеры из книги работают как в NetBeans 6.5, так и в NetBeans 6.9.1, при этом NetBeans 6.5 функционирует быстрее и занимает меньше дискового пространства, зато NetBeans 6.9.1 имеет гораздо более развитую среду редактирования и отладки. При необходимости можно установить на компьютере обе версии среды, т. к. они не мешают друг другу (хотя, конечно, это займет дополнительное дисковое пространство).
Замечания по найденным ошибкам и опечаткам просьба присылать автору по электронной почте на адрес [email protected]. Автор выражает благодарность всем, кто внес вклад в исправление ошибок предыдущих изданий (см. http://barsic.spbu.ru/ www/comlan/java_vm.html).
кандидат физико-математических наук Вадим Валериевич Монахов 12 Введение Введение Предлагаемый учебный курс можно рассматривать как краткое введение в современное программирование на Java и обзор возможностей NetBeans — одной из самых популярных и быстро развивающихся сред разработки программного обеспечения для языков Java, C, C++, Fortran, PHP, JavaScript, Ruby, Groovy и многих других.
О среде NetBeans в русскоязычной литературе рассказывается только в данной книге автора, а в иностранной — имеется около десятка таких книг, причем лишь в двух-трех из них излагается курс программирования на Java с использованием NetBeans. Поэтому читателю, желающему научиться программированию на языке Java, данное учебное пособие предоставляет уникальную возможность осуществить это с помощью наиболее современных средств, заметно облегчающих работу программиста и делающих ее гораздо более эффективной по сравнению с методиками, описанными в других книгах.
Первое издание книги, вышедшее в марте 2008 года, было полностью распродано к декабрю того же года. Оно оказалось очень популярным как среди начинающих программистов, так и среди профессионалов, переходящих с C или C++ на Java. Во втором издании была изложена работа с NetBeans версии 6.5 (первое издание основывалось на версии 6.0), а также исправлены допущенные ранее ошибки и опечатки. Кроме того, был добавлен раздел, в котором NetBeans сравнивается с другими средами разработки Java-программ, заметно расширено описание работы со строками и дописаны разделы про современные средства Java для работы с датой и временем, а также про применение в NetBeans тестовых пакетов и библиотеки JUnit 4.
В настоящем издании сохранено изложение, основанное на использовании NetBeans 6.5, однако все сказанное практически без изменений относится и к NetBeans 6.9. А различие в версии JDK вообще несущественно, и вместо JDK 6u11 рекомендуется использовать JDK 6u22, т. к. этот комплект содержит обновления системы безопасности и исправления ошибок.
Несмотря на то, что языку Java уже посвящены тысячи книг и учебных курсов, все книги, написанные до выхода JDK 5 (прежнее обозначение JDK 1.5), не соответствуют современным представлениям об этом языке.
Данное учебное пособие содержит информацию об основных синтаксических конструкциях современной версии языка Java (JDK 6), типичных ошибках их использования, рекомендации по написанию на языке Java эффективно работающих программ.
Одной из привлекательных особенностей языка Java с самого начала была бесплатность распространения базовых средств разработки SDK (Software Development Kit) и исполняющей среды Java (виртуальной Java-машины). Однако компилятор, входящий в состав SDK, работал в режиме командной строки, т. е. отставал идеологически, по крайней мере, лет на 20 от современных профессиональных компиляторов. В 2006 году корпорация Sun Microsystems пошла на беспрецедентный шаг — сделала бесплатными свои профессиональные средства разработки программного обеспечения. В настоящее время все они основаны на бесплатно распространяемой среде разработки NetBeans (платформе NetBeans), подключаемых к ней модулях (packs) и наборе библиотечных компонентов (Beans — зерен). Интересна игра слов: язык Java получил наименование по названию кофе, который любили программисты, так что Java Beans может быть расшифровано как "зерна кофе Java".
Среда NetBeans дала возможность разрабатывать программное обеспечение на языке Java с помощью самых современных методик. Она имеет развитые средства визуального проектирования пользовательского интерфейса, не уступающие Delphi, развитый редактор исходного кода программы с подсветкой ошибок непосредственно во время редактирования, а также множество других возможностей, о которых рассказывается в данной книге.
В NetBeans начиная с версии 6.5 не только существенно усовершенствован редактор исходного кода и отладчик, но и изменен сам подход к развитию среды. Если предыдущие версии ориентировались только на язык Java и в небольшой степени на C/C++, то в NetBeans 6.5 произошел переход к поддержке широкого спектра языков программирования. И если раньше корпорация Sun Microsystems, разработчик языка Java и значительной части среды NetBeans, основное внимание уделяла языку Java, то в последнее время акцент сменился — среда NetBeans и технология Java Scripting (исполнение виртуальной Java-машиной программ, написанных на отличных от Java языках программирования) оказались удобными инструментами для поддержки огромного количества языков программирования и сопутствующих им технологий. При этом связующим звеном с NetBeans и Java-машиной остается язык Java.
В состав дистрибутивов NetBeans 6.5 и 6.9 (имеются на прилагаемом к книге DVD) входят все основные модули, необходимые для программирования на Java. Кроме того, в них входит модуль "C/C++ Pack", позволяющий программировать в среде NetBeans не только на Java, но и на языках C и C++, благодаря подключению к NetBeans внешних компиляторов C/C++. Это дает возможность разрабатывать полный спектр Javaпрограмм в одной и той же среде. Раньше для создания платформо-зависимого (native) кода, используемого native-методами классов Java, требовались сторонние среды разработки программ, написанных на языках C/C++.
Среду разработки NetBeans можно установить с прилагаемого к книге DVD или свободно загрузить с сайта http://netbeans.org/. Она распространяется на условиях лицензии, дающей право использовать разработанное с помощью среды NetBeans программное обеспечение не только в некоммерческих, но и в коммерческих целях. Таким образом, теперь как начинающим разработчикам, так и крупным фирмам нет необходимости тратить деньги на покупку профессиональных средств разработки — можно работать в среде NetBeans.
Почему же это не бесплатный сыр? Среда NetBeans разрабатывается сообществом разработки свободного программного обеспечения. Значительный вклад в разработку внесла фирма Sun Microsystems, которая получала деньги не у частных лиц или маленьких компаний, а у крупных корпоративных пользователей за техническую поддержку своих бесплатно распространяемых приложений. И лидерство в данной области косвенно обеспечивало гораздо бльшие прибыли, чем продажа этих продуктов.
Java очень быстро развивается, особенно в последние годы. Из-за этого многие прежние представления и методы программирования на Java оказываются устаревшими.
Среда NetBeans развивается еще быстрее — версия 6.5, появившаяся в 2008 году, заметно превосходит по возможностям версию 6.0, вышедшую в 2007 году. Данная книга — первый шаг к изучению современных технологий на основе Java и NetBeans.
Изложение ведется на основе языка Java для JDK версии 6 и среды NetBeans версии 6.5.
Примеры, приведенные в данной книге, проверены в среде NetBeans версий 6.5 и 6. с JDK 6u11 и JDK 6u22.
Поскольку технология Java мультиплатформенна, то все изложенное справедливо как для MS Windows, так и для Solaris, Linux, Mac OS и других операционных систем.
Автор выражает благодарность рецензентам фирмы Sun Microsystems Алексею Акопяну и Алексею Уткину за полезные замечания по первоначальному варианту данного учебного пособия, Игорю Богдановичу Керницкому за содействие в подготовке примеров с native-кодом, а также жене Светлане за помощь в оформлении книги.
16 Введение ГЛ АВ А Общие представления о языке Java 1.1. Java и другие языки программирования.
Системное и прикладное программирование Язык программирования Java был создан в рамках проекта корпорации Sun Microsystems по разработке компьютерных программно-аппаратных комплексов нового поколения. Первая версия языка была официально опубликована в 1995 году. С тех пор язык Java стал стандартом "де-факто", вытеснив за десять лет языки C и C++ из многих областей программирования. В 1995 году они были абсолютными лидерами, но к 2006 году число программирующих на Java стало заметно превышать число программистов, использующих C и C++, и сейчас достигло более четырех с половиной миллионов человек. А число устройств, запрограммированных с помощью Java, превысило полтора миллиарда.
Как связаны между собой языки C, C++, JavaScript и Java? Что между ними общего и в чем они отличаются? В каких случаях следует, а в каких не следует их применять? Для того чтобы ответить на эти вопросы, нужно сначала остановиться на особенностях программного обеспечения предыдущих поколений и на современных тенденциях в развитии программного обеспечения.
Первоначально компьютеры программировались в машинных кодах. Затем появились языки ассемблера, которые заменили команды процессоров мнемоническими сокращениями, гораздо более удобными для человека, чем последовательности нулей и единиц.
Их принято считать языками программирования низкого уровня (т. е. близкими к аппаратному уровню), т. к. они ориентированы на особенности конкретных процессоров.
Программы, написанные на языках ассемблера, нельзя было переносить на компьютеры с другим типом процессора из-за несовместимости наборов команд (т. е. несовместимости на уровне исходного кода — source code).
Программы в машинных кодах (т. е. в виде последовательности нулей и единиц), соответствующих командам процессора и необходимым для них данным, нет надобности как-то преобразовывать. Их можно просто скопировать в нужное место памяти компьютера и передать управление первой команде программы (задать точку входа в программу).
Программы, написанные на каком-либо языке программирования, сначала нужно перевести из одной формы (текстовой) в другую (двоичную, т. е. в машинные коды). ПроГлава цесс такого перевода называется трансляцией (от англ. translation — "перевод", "перемещение"). Не обязательно переводить программу из текстовой формы в двоичные коды, возможен процесс трансляции с одного языка программирования на другой (или из кодов одного типа процессора в коды другого типа).
Имеются два основных вида трансляции — компиляция и интерпретация.
При компиляции первоначальный набор инструкций однократно переводится в исполняемую форму (машинные коды), а в последующем при работе программы используются только эти коды.
При интерпретации во время вызова необходимых инструкций каждый раз сначала происходит перевод инструкций из одной формы (текстовой или двоичной) в другую — в исполняемые коды процессора используемого компьютера. И только потом эти коды исполняются. Естественно, что интерпретируемые коды исполняются медленнее, чем скомпилированные, т. к. перевод инструкций из одной формы в другую обычно занимает в несколько раз больше времени, чем выполнение полученных инструкций. Но интерпретация обеспечивает бльшую гибкость по сравнению с компиляцией, и в ряде случаев без нее не обойтись.
В 1956 году появился язык Fortran — первый язык программирования высокого уровня (т. е. не ориентированный на конкретную аппаратную реализацию компьютера). Он обеспечил переносимость программ на уровне исходных кодов, но довольно дорогой ценой. Во-первых, быстродействие программ, написанных на этом языке, было в несколько раз меньше, чем для ассемблерных. Во-вторых, такие программы занимали примерно в два раза больше места в памяти компьютера, чем ассемблерные.
И, наконец, пришлось отказаться от поддержки особенностей периферийных устройств — ограничить общение с "внешним миром" простейшими возможностями, которые в программе одинаково реализовывались для ввода/вывода с помощью перфокарточного считывателя, клавиатуры, принтера, текстового дисплея и т. д. Тем не менее, языки программирования высокого уровня постепенно вытеснили ассемблер, поскольку обеспечивали не только переносимость программ, но и гораздо бльшую их надежность, а также несоизмеримо более высокую скорость разработки сложного программного обеспечения. А Fortran до сих пор остается важнейшим языком программирования для высокопроизводительных численных научных расчетов.
Увеличение аппаратных возможностей компьютеров (рост объема оперативной и дисковой памяти, значительное повышение быстродействия), а также появление разнообразных периферийных устройств привело к необходимости пересмотра того, как должны работать программы. Массовый выпуск компьютеров потребовал унификации доступа из программ к различным устройствам, обеспечивая игнорирование особенностей их аппаратной реализации. Это можно осуществить, если обращение к устройству идет не напрямую, а через прилагающуюся программу — драйвер устройства (по-английски driver означает "водитель").
Появились операционные системы — наборы драйверов и специальных программ, распределяющих ресурсы компьютера между разными программами. Соответственно, программное обеспечение стало разделяться на системное и прикладное. Системное программное обеспечение — непосредственно обращающееся к аппаратуре, прикладное — решающее какие-либо прикладные задачи и использующее аппаратные возможности компьютера не напрямую, а через вызовы программ операционной системы.
Прикладные программы стали приложениями операционной системы (сокращенно приложениями — applications). Этот термин означает, что программа может работать только под управлением операционной системы. Если на том же компьютере установить другой тип операционной системы, то программа-приложение первой операционной системы, возможно, не будет работать.
Требования к прикладным и системным программам принципиально различаются.
От системного программного обеспечения требуется максимальное быстродействие и минимальное количество занимаемых ресурсов, а также возможность доступа к любым необходимым аппаратным ресурсам. От прикладного — максимальная функциональность в конкретной предметной области. При этом быстродействие и занимаемые ресурсы не имеют значения до тех пор, пока не влияют на функциональность. Например, нет никакой разницы, реагирует ли программа на нажатие клавиши за одну десятую или за одну миллионную долю секунды. Правда, на первоначальном этапе создания прикладного программного обеспечения даже прикладные по назначению программы являлись системными по реализации, т. к. были вынуждены напрямую обращаться к аппаратуре.
Язык C был создан в 1972 году в одной из исследовательских групп Bell Laboratories при разработке операционной системы UNIX. Сначала была предпринята попытка написать операционную систему на ассемблере, но после появления в группе новых компьютеров возникла необходимость в новом платформо-независимом языке программирования высокого уровня, с помощью которого можно было бы писать операционные системы. Таким образом, язык C предназначался для создания системного программного обеспечения, и таким он остается до сих пор. Его идеология и синтаксические конструкции ориентированы на максимальную близость к аппаратному уровню реализации операций — в той степени, в какой он может быть обеспечен на аппаратнонезависимом уровне. При этом главным требованием была максимальная скорость работы и минимальное количество занимаемых ресурсов, а также возможность доступа ко всем аппаратным средствам. Язык C — это язык процедурного программирования, т. к. его базовыми конструкциями являются подпрограммы. В общем случае подпрограммы принято называть подпрограммами-процедурами (откуда и идет название "процедурное программирование") и подпрограммами-функциями. Но в C имеются только подпрограммы-функции. Обычно их называют просто функциями.
Язык C произвел настоящую революцию в разработке программного обеспечения, получил широкое распространение и стал промышленным стандартом. Он до сих пор применяется для написания операционных систем и программирования микроконтроллеров. Но мало кто в полной мере осознает причины его популярности. В чем они заключались? В том, что он смог обеспечить необходимую функциональность программного обеспечения в условиях низкой производительности компьютеров, крайней ограниченности их ресурсов и неразвитости периферийных устройств! При этом повторилась та же история, что и с языком Fortran, но теперь уже для языка системного программирования. Переход на язык программирования высокого уровня, но с минимальными потерями по производительности и ресурсам, дал большие преимущества.
Большое влияние на развитие теории программирования оказал язык Pascal, разработанный в 1974 году швейцарским профессором Никлаусом Виртом. В этом проекте сочетались два оригинальных замысла. Первый — собственно язык Pascal, предназначенГлава ный для обучения идеям структурного программирования. Второй — идея виртуальной машины. Никлаус Вирт предложил обеспечивать переносимость программ, написанных на Pascal, за счет компиляции их в набор команд некой абстрактной P-машины (P — сокращение от Pascal), а не в исполняемый код конкретной аппаратной платформы. А на каждой аппаратной платформе должна была работать программа, интерпретирующая эти коды. Говорят, что такая программа эмулирует (т. е. имитирует) систему команд несуществующего процессора. А саму программу называют виртуальной машиной.
В связи с ограниченностью ресурсов компьютеров и отсутствием в Pascal средств системного программирования этот язык не смог составить конкуренцию языку C, т. к.
практически все промышленное программирование вплоть до середины последнего десятилетия ХХ века по реализации было системным. Идеи P-машины были в дальнейшем использованы и значительно усовершенствованы в Java.
Развитие теории и практики программирования привело к становлению в 1967— 1972 годах нового направления — объектного программирования, основанного на концепциях работы с классами и объектами. Оно обеспечило принципиально новые возможности по сравнению с процедурным. Были предприняты попытки расширения различных языков путем введения в них конструкций объектного программирования.
В 1982 году Бьерн Страуструп путем такого расширения языка C создал язык, который он назвал "C с классами". В 1983 году после очередных усовершенствований им был создан первый компилятор языка C++. Два плюса означают: "язык C с очень большим количеством добавлений" и одновременно — "новое, увеличенное на один по сравнению с прежним, значение" (игра понятий: в C существует оператор "++").
Язык C++ является надмножеством над языком C — на нем можно писать программы как на "чистом C", без использования каких-либо конструкций объектного программирования. В связи с этим, а также и с дополнительными преимуществами объектного программирования, язык С++ быстро приобрел популярность и стал промышленным стандартом (сначала "де-факто", а потом и "де-юре"). Так что в настоящее время C++ признан базовым языком системного программирования. Длительное время он использовался и для написания прикладных программ. Но, как мы уже знаем, требования к прикладным программам совпадают с требованиями к системным только в том случае, когда быстродействие компьютера можно рассматривать как низкое, а ресурсы компьютера — малыми. Кроме этого, у языков C и C++ имеются еще два принципиальных недостатка: а) низкая надежность на уровне как исходного, так и исполняемого кода;
б) отсутствие переносимости на уровне исполняемого кода. С появлением компьютерных сетей эти недостатки стали очень существенным ограничивающим фактором, поскольку вопросы безопасности при работе в локальных, а особенно в глобальных сетях приобретают первостепенную значимость.
В 1995 году появились сразу два языка программирования, имеющие в настоящее время огромное значение: Java, разработанный в корпорации Sun, и JavaScript, созданный в небольшой фирме Netscape Communication, получившей к тому времени известность благодаря браузеру Netscape Navigator.
Язык Java создавался как универсальный, предназначенный для прикладного программирования в неоднородных компьютерных сетях как со стороны клиентского компьюОбщие представления о языке Java тера, так и со стороны сервера. В том числе для использования на тонких аппаратных клиентах (устройствах малой вычислительной мощности с крайне ограниченными ресурсами). Скомпилированные программы Java работают только под управлением виртуальной Java-машины, поэтому их называют приложениями Java. Синтаксис операторов Java практически полностью совпадает с синтаксисом языка C, но в отличие от C++, Java это не расширение C, а совершенно независимый язык, со своими собственными синтаксическими правилами. Он гораздо сильнее типизирован по сравнению с C и C++, т. е. вносит больше ограничений на действия с переменными и величинами разных типов. Например, в C/C++ нет разницы между целочисленными числовыми, булевыми и символьными величинами, а также адресами в памяти. Так, можно умножить символ на булево значение true (истина), из которого вычтено целое число, и разделить результат на адрес! В Java введен вполне разумный запрет на почти все действия такого рода.
JavaScript создавался как узкоспециализированный прикладной язык программирования HTML-страниц, расширяющий возможности HTML, и он в полной мере отвечает этим потребностям до сих пор. Про язык HTML, являющийся основой для создания WWW-документов, более подробно будет рассказано в главе 11.
Следует подчеркнуть, что язык JavaScript не имеет никакого отношения к Java. Слово "script" означает сценарий. Включение слова "Java" в название JavaScript — рекламный трюк фирмы Netscape Communication. Язык JavaScript также C-образен, но в отличие от Java, интерпретируемый. Основное его назначение — программное управление элементами WWW-документов. Языки HTML и XML позволяют задавать статический, неизменный внешний вид документов, с их помощью невозможно запрограммировать реакцию на действия пользователя. JavaScript позволяет ввести элементы программирования в поведение документа. Программы, написанные на JavaScript, встраиваются в документы в виде исходных кодов (сценариев) и имеют небольшой размер. Для упрощения работы с динамически формируемыми документами JavaScript имеет свободную типизацию: переменные меняют тип по результату присваивания. Поэтому программы JavaScript гораздо менее надежны, чем C/C++, не говоря уже про Java.
Java, JavaScript и C++ относятся к объектно-ориентированным языкам программирования, все они имеют C-образный синтаксис операторов. Но как объектные модели, так и базовые конструкции этих языков (за исключением синтаксиса операторов) принципиально различны. Ни один из них не является версией или упрощением другого — это совсем разные языки, предназначенные для различных целей.
Итак:
Java — универсальный язык прикладного программирования;
JavaScript — узкоспециализированный язык программирования HTML-документов;
C++ — универсальный язык системного программирования.
В 2000 году в корпорации Microsoft была разработана платформа.NET (читается "дотнет", DotNet — в переводе с английского "точка NET"). Она стала альтернативой платформе Java и во многом повторила ее идеи. Основное различие заключалось в том, что для этой платформы можно было использовать произвольное количество языков программирования, а не один. Причем классы.NET оказываются совместимыми как в целях наследования, так и по исполняемому коду независимо от языка, на котором они написаны. Важнейшим языком.NET стал Java-образный язык C# (читается "Си шарп").
Фактически, C# унаследовал от Java большинство особенностей — динамическую объектную модель, сборку "мусора", основные синтаксические конструкции, хотя он вполне самостоятельный язык программирования, имеющий много привлекательных черт.
В частности, компонентные модели Java и C# принципиально отличаются.
Java стал первым универсальным C-образным языком прикладного программирования, что обеспечило легкость перехода на этот язык большого числа программистов, знакомых с C и C++. А наличие средств строгой проверки типов, ориентация на работу с компьютерными сетями, переносимость на уровне исполняемого кода и поддержка платформо-независимого графического интерфейса, а также запрет прямого обращения к аппаратуре обеспечили выполнение большинства требований, предъявлявшихся к языку прикладного программирования. Чем больше становятся быстродействие и объем памяти компьютеров, тем больше потребность в разделении прикладного и системного программного обеспечения. Соответственно, для прикладных программ исчезает необходимость напрямую обращаться к памяти и другим аппаратным устройствам компьютера. Поэтому среди прикладных программ с каждым годом растет доля программного обеспечения, написанного на Java и языках.NET. Но как по числу программистов, так и по числу устройств, использующих соответствующие платформы, Java в настоящее время лидирует с большим отрывом.
1.2. Виртуальная Java-машина, байт-код, JIT-компиляция. Категории программ, написанных на языке Java Первоначально слово "программа" означало последовательность инструкций процессора для решения какой-либо задачи. Эти инструкции представляли собой машинные коды, и разницы между исходным и исполняемым кодом программы не было. Разница появилась, когда программы стали писать на языках программирования. При этом программой стали называть как текст, содержащийся в файле с исходным кодом, так и исполняемый файл.
Для устранения неоднозначности термина "программа" исполняемый код программы принято называть приложением (application). Термин "приложение" — сокращение от фразы "приложение операционной системы". Он означает, что исполняемый код программы может работать только под управлением соответствующей операционной системы. Работа под управлением операционной системы позволяет избежать зависимости программы от устройства конкретного варианта аппаратуры на компьютере, где она должна выполняться. Например, как автору программы, так и пользователю совершенно безразлична аппаратная реализация устройства, с которого считывается информация: будет ли это жесткий диск с одной, двумя или шестнадцатью считывающими головками, или это будет CD-привод, DVD-привод, или еще какой-либо другой тип носителя. Но переносимость обычных приложений ограничивается одним типом операционных систем. Например, приложение MS Windows не будет работать под Linux, и наоборот. Существует возможность исключить зависимость приложения от операционной системы, введя выполнение его команд не средствами операционной системы, а исполняющей средой — программой, контролирующей работу приложения и выполняющей его вызовы. Программы, написанные на языке Java, выполняются исполняющей средой — виртуальной Java-машиной, и поэтому обладают переносимостью на любую операционную систему, где имеется соответствующая Java-машина.
Благодаря этому они являются не приложениями какой-либо операционной системы, а приложениями Java.
Программы, написанные на языке Java, представляют собой наборы классов (о классах будет рассказано несколько позже) и сохраняются в текстовых файлах с расширением java. При компиляции текст программы переводится (транслируется) в двоичные файлы с расширением class. Такие файлы содержат байт-код, представляющий собой совокупность инструкций для абстрактного Java-процессора в виде байтовых последовательностей команд этого процессора и данных к ним. Для того чтобы выполнить байт-код на каком-либо компьютере, его нужно перевести в инструкции для соответствующего процессора. Именно этим и занимается Java-машина. Первоначально байт-код всегда интерпретировался следующим образом: каждый раз, когда встречалась какаялибо инструкция Java-процессора, она переводилась в последовательность инструкций процессора компьютера, что, естественно, значительно замедляло работу приложений Java.
В настоящее время используется более сложная схема, называемая JIT-компиляцией (Just-In-Time), — это компиляция "по ходу дела", "на лету". Когда какая-либо инструкция (или набор инструкций) Java-процессора выполняется в первый раз, происходит компиляция соответствующего ей байт-кода с сохранением скомпилированного кода в специальном буфере. При последующем вызове той же инструкции вместо ее интерпретации скомпилированный код извлекается из буфера. Поэтому интерпретация происходит только при первом вызове инструкции.
Сложные оптимизирующие JIT-компиляторы действуют еще изощренней. Поскольку обычно компиляция инструкции идет гораздо дольше по сравнению с интерпретацией, время ее выполнения в первый раз при наличии JIT-компиляции может заметно отличаться в худшую сторону по сравнению с "чистой" интерпретацией. Поэтому бывает выгоднее сначала запустить процесс интерпретации, а параллельно ему в фоновом режиме компилировать инструкцию. Только после окончания процесса компиляции при последующих вызовах инструкции будет исполняться ее скомпилированный код (а до этого все ее вызовы будут интерпретироваться). Разработанная Sun виртуальная машина HotSpot осуществляет JIT-компиляцию только тех участков байт-кода, которые критичны ко времени выполнения программы. При этом по ходу работы программы происходит оптимизация скомпилированного кода.
Благодаря компиляции программ Java в платформо-независимый байт-код обеспечивается переносимость этих программ не только на уровне исходного кода, но и на уровне скомпилированных приложений. Конечно, при этом на компьютере, где выполняется приложение, должна быть установлена программа виртуальной Java-машины (Java Virtual Machine — JVM), скомпилированная в коды соответствующего процессора (native code — платформо-зависимый код). На одном и том же компьютере может быть несколько Java-машин разных версий или от разных производителей. Спецификация Java-машины и требования к компилятору языка Java открытые, поэтому различные фирмы (а не только Sun) разрабатывают компиляторы Java и Java-машины.
Обычно приложение операционной системы запускается с помощью средств самой операционной системы. Приложение Java, напротив, исполняется с помощью виртуальной Java-машины, которая сама является приложением операционной системы. Таким образом, сначала стартует Java-машина. Она получает в качестве параметра имя файла с компилированным кодом класса. В этом классе ищется и запускается на выполнение подпрограмма с именем main.
Приложения Java обладают не только хорошей переносимостью, но и высокой скоростью работы. Однако даже при наличии JIT-компиляции они все-таки выполняются медленнее, чем программы, написанные на C или C++. Это связано с тем, что JITкомпиляция создает не настолько оптимальный код, как многопроходный компилятор C/C++ (он имеет возможность тратить много времени и ресурсов на поиск конструкций программы, которые можно оптимизировать). А JIT-компиляция происходит "на лету", в условиях жесткой ограниченности времени и ресурсов. Для решения этой проблемы были разработаны компиляторы программ Java в код конкретных программноаппаратных платформ (native code — платформо-зависимый код). Например, свободно распространяемый фондом GNU компилятор GCJ (http://gcc.gnu.org/java/). Правда, заметные успехи Sun в усовершенствовании Java-машины позволили практически достичь, а в ряде случаев даже обогнать по быстродействию программы, написанные на других языках, и отказаться от статической компиляции в платформо-зависимый код.
В частности, приложения Java, активно занимающиеся выделением/высвобождением памяти, работают быстрее своих аналогов, написанных на C/C++, благодаря специальному механизму программных слотов памяти (slot — паз, отверстие для вставки чеголибо).
Виртуальная Java-машина не только исполняет байт-код (интерпретирует его, занимается JIT-компиляцией и исполняет JIT-компилированный код), но и выполняет ряд других функций (например, взаимодействует с операционной системой, обеспечивая доступ к файлам или поддержку графики), а также реализует автоматическое высвобождение памяти, занятой ненужными объектами, — так называемую сборку мусора (garbage collection).
Программы Java можно разделить на несколько основных категорий.
Приложение (application) — аналог обычной прикладной программы.
Апплет (applet) — специализированная программа с ограниченными возможностями, работающая в окне WWW-документа под управлением браузера.
Мидлет (midlet) — специализированная программа с ограниченными возможностями, работающая на мобильном устройстве. В настоящее время мидлеты — один из наиболее популярных сегментов рынка программного обеспечения, пишущегося на языке Java.
Сервлет (servlet) — специализированная программа с ограниченными возможностями, работающая в WWW на стороне сервера. Используется преимущественно в рамках технологии JSP (Java Server Pages — серверных страниц Java) для программирования WWW-документов со стороны сервера и обработки отсылаемой на сервер информации.
Серверное приложение (Enterprise application) — предназначено для многократного выполнения на стороне сервера.
Библиотека (Java Class Library — библиотека классов, либо NetBeans Module — модуль платформы NetBeans) — предназначена для многократного использования программами Java.
Между приложениями и апплетами Java существует принципиальное различие: приложение запускается непосредственно с компьютера пользователя и имеет доступ ко всем ресурсам компьютера наравне с любыми другими программами. Апплет же загружается из WWW с постороннего сервера, причем из-за самой идеологии WWW-сайт, с которого загружен апплет, в общем случае не может быть признан надежным. А сам апплет может передавать данные на произвольный сервер в WWW. Поэтому, для того чтобы избежать риска утечки конфиденциальной информации с компьютера пользователя или совершения враждебных действий, у апплетов убраны многие возможности, имеющиеся у приложений.
Сервлеты — это приложения Java, запускаемые на стороне сервера. Они обладают возможностью доступа к файловой системе и другим ресурсам сервера через набор управляющих конструкций, предопределенных в рамках технологии JSP и пакета javax.servlet. Кроме того, они имеют доступ к содержимому HTTP-запросов со стороны клиентского компьютера, т. е. того компьютера, на котором работает пользователь.
HTTP (HyperText Transport Protocol) — это протокол передачи WWW-документов через Интернет.
Технология JSP заключается в наличии дополнительных конструкций (тегов) в HTMLили XML-документах, которые позволяют серверу автоматически генерировать и компилировать сервлеты. В результате удается очень просто и удобно обрабатывать данные или элементы документа, а также внедрять в нужные места документа результаты обработки. Автоматическая генерация сервлетов происходит всего один раз — перед первой обработкой документа с тегами JSP на стороне сервера, поэтому код JSP выполняется достаточно быстро, но конечно требует, чтобы была установлена соответствующая Java-машина (например, входящая в состав сервера GlassFish — программного обеспечения, обеспечивающего поддержку большого количества необходимых серверных возможностей для работы в WWW). Отметим, что программный сервер GlassFish, основанный на кодах Sun Application Server, распространяется бесплатно и входит в состав NetBeans 6.5.
Более подробная информация о сетевом программировании и серверных приложениях Java будет изложена в главе 11.
Первоначально корпорация Sun Microsystems позиционировала Java как язык, обеспечивающий развитые графические возможности WWW-документов благодаря включению в них апплетов. Однако в настоящее время основные области применения Java — прикладное программирование на основе приложений, страниц JSP и сервлетов, а также других видов серверных программ. При этом апплеты играют незначительную роль.
Виртуальную Java-машину часто называют исполняющей средой (Java Runtime Environment — JRE).
Существуют два основных способа установки Java-машины на клиентский компьютер:
JRE из поставки Java Development Kit (JDK) — комплект разработки программного обеспечения на языке Java. Как синоним может употребляться термин SDK — Software Development Kit (комплект разработки программного обеспечения);
специализированный вариант JRE в составе интернет-браузера, называющийся Java plugin.
Комплект последних версий JDK можно свободно загружать с сайта Sun http:// java.sun.com/.
При использовании апплетов требуется, чтобы в состав браузера входил специализированный комплект JRE. Как правило, он поставляется вместе с браузером и может при необходимости обновляться. Для MS Internet Explorer такой комплект и его обновления могут быть свободно загружены с сайта http://www.java.com/.
Имеется возможность установки Java-машины от различных производителей (не обязательно устанавливать комплект JDK от Sun). На одном и том же компьютере можно установить сразу несколько различных Java-машин (в том числе комплекты JDK разных версий). Правда, опыт показывает, что при этом некоторые программы, написанные на Java, теряют работоспособность (частично или полностью).
Комплекты JDK классифицируются исходя из версии Java (языка программирования и, соответственно, Java-машины) и типа создаваемых приложений. Так, ко времени написания данного текста выходили версии JDK 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6 и готовится к выходу 1.7. В каждой версии есть ряд подверсий, не сопровождающихся изменением языка программирования, а связанных в основном с исправлением ошибок или внесением небольших изменений в библиотеки (например, 1.4.1_01 или 1.5.0_04).
Версии Java 1.0 и 1.1 принято называть Java 1. Все версии Java, начиная c 1.2, называют Java 2. Однако более надежно классифицировать по номеру JDK, т. к. язык Java для версии JDK 1.5 заметно отличается по возможностям от языка Java для более ранних версий JDK — в него добавлено большое количество новых синтаксических конструкций, а также изменен ряд правил. Поэтому код, правильный в Java для версии JDK 1.5, может оказаться неправильным в Java для версии JDK 1.4 (не говоря уже про Java для версии JDK 1.3 или 1.2). Кроме того, начиная с JDK 1.5 компания Sun перестала использовать в названиях комплектов программного обеспечения термин "Java 2" и происходящие от него сокращения вида j2, а в нумерации комплектов JDK отказалась от префикса "1". Поэтому сейчас принято говорить о версиях JDK 5 или JDK 6, а не о JDK 1.5 или JDK 1.6. Но соответствующие папки при установке среды на компьютере все-таки называются jdk1.5 и jdk1.6.
Комплекты разработки JDK одной версии отличаются по типу создаваемых с их помощью приложений. По применяемым средствам разработки и условиям выполнения приложений Java различают три платформы:
Микроиздание — Java Platform, Micro Edition (Java ME) http://java.sun.com/javame/ для программирования "тонких аппаратных клиентов" (т. е. устройств, обладающих малыми ресурсами — наладонных компьютеров, сотовых телефонов, микроконтроллеров, смарт-карт). Старое название J2ME. Для разработки приложений применяется не JDK, а специальный набор инструментов (Sun Java Wireless Toolkit for CLDC, Sun Java Toolkit for CDC, NetBeans 6.5, инструментарий от других производителей). Приложения Java работают под управлением одной из двух имеющихся для этой платформы вариантов Java-машины: максимально облегченной килобайтной виртуальной машины KVM или несколько более мощной виртуальной машины издание — Java Platform, Standard Edition (Java SE) http:// Стандартное java.sun.com/javase/ для программирования "толстых клиентов" (т. е. устройств, обладающих достаточно большими ресурсами — обычных компьютеров и серверов).
Старое название J2SE. Основой средств разработки служит JDK. Приложения Java работают под управлением Java-машины JVM (Java Virtual Machine).
Корпоративное издание — Java Platform, Enterprise Edition (Java EE) http:// java.sun.com/javaee/ для написания серверного программного обеспечения. Старое название J2EE. Является надстройкой над платформой Java SE, поэтому все приложения Java EE работают с использованием классов Java SE и под управлением JVM.
В SDK данной платформы входит мощный программный сервер Sun Java System Application Server (сервер приложений Java), а также большое число других исполняющих сред, основанных на технологиях Java.
При распространении какого-либо продукта, написанного на Java для платформы Java SE, возможна установка только программного обеспечения Java-машины (JRE — Java Runtime Environment). Например, в случае Java 6 update 7 (обновление 7) комплект JDK назывался jdk1.6.0_07, и ему будет соответствовать комплект jre1.6.0_07. При этом создавалась папка с именем jre1.6.0_07 с вложенными папками bin и lib. Начиная с Java 6 update 10, среда jre устанавливается в папку jre6 без указания номера обновления — эта и более поздние версии допускают обновление JRE без скачивания и переустановки всего дистрибутива.
Фактически, Java 6 update 10 — новый этап в развитии Java, и его отличие от предыдущей версии Java 6 update 7 (обновления 8 и 9 отсутствовали) гораздо больше, чем различия между Java 5 и Java 6. Очередной большой этап — предстоящий переход к Java 7.
Состав jre6 достаточно прост. В папке bin содержатся файлы и папки, необходимые для работы Java-машины и дополнительных инструментов для работы с ней в специальных режимах. В папке lib находятся вспомогательные файлы и библиотеки, в основном связанные с параметрами настроек системы.
Также возможна установка целиком JDK. Например, при установке Java 1.6 update создается папка jdk1.6.0_11 с вложенными папками:
bin — содержатся файлы инструментов разработки;
demo — файлы примеров с исходными кодами;
include — заголовки файлов C для доступа к ряду библиотек Java и отладчику виртуальной Java-машины на платформо-зависимом уровне — на основе интерфейсов JNI (Java Native Interface) и JVMDI (Java Virtual Machine Debugging Interface) соответственно;
jre — файлы, необходимые для работы с виртуальной Java-машиной;
lib — ряд библиотек и сопроводительных файлов для работы инструментов из папки sample — примеры с исходными кодами.
В папке jdk1.6.0_11 содержится также архив src.zip с исходными кодами стандартных классов Java.
Следует отметить, что комплекты JRE, входящие в состав JDK и поставляемые отдельно от JDK, заметно различаются. Это связано с тем, что в отдельно поставляемом комплекте не нужны средства, предназначенные для отладки приложений и специальных отладочных режимов работы с Java-машиной (управления загрузкой, профилирования, проверки стека и т. д.).
К сожалению, в JDK отсутствует даже самая простейшая документация с описанием назначения имеющихся в нем инструментов, там даны лишь ссылки на сайт компании Sun, где можно найти эту информацию. В табл. 1.1 перечислено назначение основных инструментов.
Утилита Назначение javac Компилятор в режиме командной строки для программ, написанных на языке java Утилита для запуска в режиме командной строки откомпилированных программприложений appletviewer Утилита для запуска на исполнение и отладку апплетов без браузера. При этом не гарантируется работоспособность отлаженного апплета в браузере jdb Отладчик программ, написанных на языке Java javadoc Генератор документации по классам на основе комментариев, начинающихся jar Создание и управление Java-архивами jar javah Генератор заголовочных файлов C/C++ для подключения к программам Java внешних библиотек C/C++ на основе интерфейса JNI javap Дизассемблер классов extcheck Утилита для обнаружения конфликтов между файлами архивов jar native2ascii Утилита для конвертации в режиме командной строки параметра, передаваемого в виде текста на национальном алфавите, в последовательность символов Кроме того, имеются средства поддержки работы в WWW и корпоративных сетях (интранет) с интерфейсом RMI — интерфейсом удаленного вызова методов (Remote Methods Invocation). Это программы rmic, rmiregistry, rmid. Также присутствуют средства поддержки информационной безопасности keytool, jarsigner, policytool и ряд других категорий утилит.
Подчеркнем, что набор утилит JDK рассчитан на морально устаревший режим командной строки, и что в большинстве случаев гораздо удобнее и правильнее пользоваться современной профессиональной средой разработки NetBeans. Для ее работы из JDK необходим только комплект JRE.
1.3. Алфавит языка Java.
Десятичные и шестнадцатеричные цифры и целые числа. Зарезервированные слова Подробную информацию об алфавите языка Java и основных синтаксических конструкциях можно найти на сайте http://java.sun.com/docs/books/jls/index.html (на английском языке).
Алфавит языка Java Алфавит языка Java состоит из букв, десятичных цифр, разделителей и специальных символов. Буквами считаются латинские буквы (кодируются в стандарте ASCII), буквы национальных алфавитов (кодируются в стандарте Unicode, кодировка UTF-16), а также соответствующие им символы, кодируемые управляющими последовательностями (о них будет рассказано чуть позже).
Буквы и цифры можно использовать в качестве идентификаторов (т. е. имен) переменных, методов и других элементов языка программирования. Правда, при наличии в идентификаторах букв национальных алфавитов в ряде случаев могут возникнуть проблемы — эти символы будут показываться в виде вопросительных знаков.
Непосредственно как буквы рассматривается только часть символов национальных алфавитов, остальные — специальные символы — используются в качестве операторов и разделителей языка Java и не могут входить в состав идентификаторов.
Латинские буквы ASCII:
ABCD...XYZ — заглавные (прописные);
abcd...xyz — строчные.
Дополнительные буквенные символы ASCII:
_ — знак подчеркивания;
$ — знак доллара.
Национальные буквы на примере русского алфавита:
АБВГ...ЭЮЯ — заглавные (прописные);
абвг...эюя — строчные.
Десятичные цифры:
Разделители (их девять, задаются как символы ASCII):
Десятичные и шестнадцатеричные цифры и целые числа Целые числовые константы в исходном коде Java (так называемые литерные константы) могут быть десятичными или шестнадцатеричными. Они записываются либо символами ASCII, либо символами Unicode следующим образом.
Десятичные константы записывают как обычно (например, –137).
Константы-значения, записанные в виде последовательности символов (литер), называют литерными (иногда — литералами). В Java литерные константы бывают не только числовыми, но и булевыми (значения true и false), символьными (например, 'a', 'b', '1', '2'), строковыми (например, "Это - строка"). Также имеется особая литерная константа null.
Шестнадцатеричная литерная константа целого типа начинается с символов 0x или 0X (цифра 0, после которой следует латинская буква X), затем идет само число в шестнадцатеричной нотации. Например:
0x10 соответствует 1016 = 16;
0x2F соответствует 2F16 = 47 и т. д.
О шестнадцатеричной нотации будет рассказано чуть позже.
Ранее иногда применялись восьмеричные числа, в языках C/C++, а также и в Java их записывали в виде числа, начинающегося с цифры 0 (т. е. 010 означало 108 = 8).
В настоящее время в программировании восьмеричные числа практически не применяют, а неадекватное использование ведущего нуля может приводить к логическим ошибкам в программе.
Целая литерная константа в обычной записи имеет тип int. Если после константы добавить букву L (или l, что хуже видно в тексте, хотя в среде разработки выделяется цветом), то она будет иметь тип long, обладающий более широким диапазоном значений, чем тип int.
Поясним теперь, что такое шестнадцатеричная нотация записи чисел и зачем она нужна.
Информация представляется в компьютере в двоичном виде — как последовательность битов. Бит — это минимальная порция информации, он может быть представлен в виде ячейки, в которой хранится ноль или единица. Но бит — слишком мелкая единица, поэтому в компьютерах информация хранится, кодируется и передается байтами — порциями по 8 битов.
В данной книге под "ячейкой памяти" будет пониматься непрерывная область памяти (с последовательно идущими адресами), выделенная программой для хранения данных.
На рисунках мы будем изображать ячейку прямоугольником, внутри которого находятся хранящиеся в ней данные. Если у ячейки имеется имя, оно будет выведено рядом с этим прямоугольником.
Мы привыкли работать с числами, записанными в так называемой десятичной системе счисления. В этой системе имеются 10 цифр (от 0 до 9), а в числе имеются десятичные разряды. Каждый разряд слева имеет вес 10 по сравнению с предыдущим, т. е. для получения значения числа, соответствующего цифре в каком-то разряде, стоящую в нем цифру нужно умножать на 10 в соответствующей степени (т. е. 52 = 510 + 2;
137 = 1102 + 3101 + 7, и т. п.).
В программировании десятичной системой счисления пользоваться не всегда удобно, т. к. в компьютерах информация организована в виде битов, байтов и более крупных порций. Человеку неудобно оперировать данными в виде длинных последовательностей нулей и единиц. В настоящее время в программировании стандартной является шестнадцатеричная система записи чисел. Например, с ее помощью естественным образом кодируется цвет, устанавливаются значения отдельных битов числа, осуществляется шифрование и дешифрование информации, и т. д. В этой системе счисления все очень похоже на десятичную, но только не 10, а 16 цифр, и вес разряда не 10, а 16. Первые десять цифр записывают обычными десятичными цифрами, а недостающие цифры (бльшие 9) — заглавными латинскими буквами: A, B, C, D, E, F:
0123456789ABCDEF То есть: A = 10, B = 11, C = 12, D = 13, E = 14, F = 15.