Главная              Рефераты - Разное

Общие представления о языке Java 5 - реферат

Содержание

Введение.......................................................................................................................................................................................... 6

Глава 1. Общие представления о языке Java........................................................................................................................ 7

1.1. Java и другие языки программирования. Системное и прикладное программирование............................ 7

1.2. Виртуальная Java-машина, байт-код, JIT-компиляция. Категории программ, написанных на языке Java 11

1.3.Алфавит языка Java. Десятичные и шестнадцатеричные цифры и целые числа. Зарезервированные слова 16

Алфавит языка Java......................................................................................................................................................... 16

Десятичные и шестнадцатеричные цифры и целые числа................................................................................... 16

Зарезервированные слова языка Java........................................................................................................................ 18

1.4. Управляющие последовательности. Символы Unicode. Специальные символы........................................ 18

Управляющие последовательности............................................................................................................................ 18

Простые специальные символы................................................................................................................................... 19

Составные специальные символы............................................................................................................................... 20

1.5.Идентификаторы. Переменные и типы. Примитивные и ссылочные типы..................................................... 21

Краткие итоги по главе 1..................................................................................................................................................... 24

Задания..................................................................................................................................................................................... 25

Глава 2. Объектно-ориентированное проектирование и платформа NetBeans....................................................... 26

2.1.Процедурное и объектно-ориентированное программирование. Инкапсуляция........................................ 26

2.2. Работа со ссылочными переменными. Сборка мусора...................................................................................... 29

2.3. Проекты NetBeans. Пакеты. Уровни видимости классов. Импорт классов................................................... 33

2.4. Базовые пакеты и классы Java................................................................................................................................... 35

2.5. Создание в NetBeans простейшего приложения Java......................................................................................... 38

2.6. Компиляция файлов проекта и запуск приложения............................................................................................. 42

2.7. Структура проекта NetBeans..................................................................................................................................... 43

2.8. Создание в NetBeans приложения Java с графическим интерфейсом............................................................ 46

2.9. Редактор экранных форм............................................................................................................................................. 49

2.10. Внешний вид приложения......................................................................................................................................... 53

2.11. Ведение проектов........................................................................................................................................................ 54

2.11. Редактирование меню экранной формы............................................................................................................... 56

2.12. Создание нового класса............................................................................................................................................ 58

2.13. Документирование исходного кода в Java.......................................................................................................... 61

2.14. Основные компоненты пакетов swing и awt......................................................................................................... 65

2.15. Технологии Java и .Net............................................................................................................................................... 70

Краткие итоги по главе 2..................................................................................................................................................... 72

Задания..................................................................................................................................................................................... 73

Глава 3. Примитивные типы данных и операторы для работы с ними...................................................................... 74

3.1.Булевский (логический) тип......................................................................................................................................... 74

3.2.Целые типы, переменные, константы........................................................................................................................ 75

3.3.Основные операторы для работы с целочисленными величинами................................................................. 77

3.4.Вещественные типы и класс Math............................................................................................................................. 78

3.5.Правила явного и автоматического преобразования типа при работе с числовыми величинами......... 81

3.6. Оболочечные классы. Упаковка (boxing) и распаковка (unboxing)................................................................. 83

3.7.Приоритет операторов.................................................................................................................................................. 84

3.8.Типы-перечисления (enum).......................................................................................................................................... 85

Краткие итоги по главе 3..................................................................................................................................................... 88

Задания..................................................................................................................................................................................... 89

Глава 4. Работа с числами в языке Java............................................................................................................................... 91

4.1 Двоичное представление целых чисел..................................................................................................................... 91

Позиционные и непозиционные системы счисления.............................................................................................. 91

Двоичное представление положительных целых чисел....................................................................................... 92

Двоичное представление отрицательных целых чисел. Дополнительный код............................................. 93

Проблемы целочисленной машинной арифметики................................................................................................ 94

Шестнадцатеричное представление целых чисел и перевод из одной системы счисления в другую.... 95

4.2. Побитовые маски и сдвиги.......................................................................................................................................... 97

4.3. Двоичное представление вещественных чисел.................................................................................................. 100

Двоичные дроби............................................................................................................................................................. 100

Мантисса и порядок числа......................................................................................................................................... 100

Стандарт IEEE 754 представления чисел в формате с плавающей точкой*............................................... 102

Краткие итоги по главе 4.................................................................................................................................................. 106

Задания.................................................................................................................................................................................. 106

Глава 5. Управляющие конструкции.................................................................................................................................. 108

Составной оператор..................................................................................................................................................... 108

Условный оператор if................................................................................................................................................ 108

Оператор выбора switch.............................................................................................................................................. 112

Условное выражение …?... : ….................................................................................................................................. 112

Операторы инкремента ++ и декремента --............................................................................................................ 113

Оператор цикла for..................................................................................................................................................... 113

Оператор цикла while – цикл с предусловием.................................................................................................. 117

Оператор цикла do...while – цикл с постусловием...................................................................................... 118

Операторы прерывания continue, break, return, System.exit............................................................................... 119

Краткие итоги по главе 5.................................................................................................................................................. 122

Задания.................................................................................................................................................................................. 122

Глава 6. Начальные сведения об объектном программировании.............................................................................. 123

Наследование и полиморфизм. UML-диаграммы...................................................................................................... 123

Функции. Модификаторы. Передача примитивных типов в функции................................................................. 129

Локальные и глобальные переменные. Модификаторы доступа и правила видимости. Ссылка this........ 132

Передача ссылочных типов в функции. Проблема изменения ссылки внутри подпрограммы.................... 134

Наследование. Суперклассы и подклассы. Переопределение методов.............................................................. 139

Наследование и правила видимости. Зарезервированное слово super............................................................... 144

Статическое и динамическое связывание методов. Полиморфизм....................................................................... 146

Базовый класс Object......................................................................................................................................................... 147

Конструкторы. Зарезервированные слова super и this. Блоки инициализации................................................. 149

Удаление неиспользуемых объектов и метод finalize. Проблема деструкторов для сложно устроенных объектов 152

Перегрузка методов............................................................................................................................................................ 152

Правила совместимости ссылочных типов как основа использования полиморфного кода. Приведение и проверка типов.................................................................................................................................................................................................. 155

Рефакторинг.......................................................................................................................................................................... 157

Reverse engineering – построение UML-диаграмм по разработанным классам................................................ 160

Краткие итоги по главе 6.................................................................................................................................................. 166

Задания.................................................................................................................................................................................. 167

Глава 7. Важнейшие объектные типы................................................................................................................................ 169

Массивы................................................................................................................................................................................. 169

Коллекции, списки, итераторы........................................................................................................................................ 173

Работа со строками в Java. Строки как объекты. Классы String, StringBuffer и StringBuilder....................... 176

Работа с графикой............................................................................................................................................................... 180

Исключительные ситуации.............................................................................................................................................. 183

Обработка исключительных ситуаций................................................................................................................... 183

Иерархия исключительных ситуаций...................................................................................................................... 185

Объявление типа исключительной ситуации и оператор throw....................................................................... 186

Объявление метода, который может возбуждать исключительную ситуацию. Зарезервированное слово throws............................................................................................................................................................................................. 187

Работа с файлами и папками........................................................................................................................................... 188

Работа с файлами и папками с помощью объектов типа File............................................................................ 188

Выбор файлов и папок с помощью файлового диалога..................................................................................... 192

Работа с потоками ввода-вывода.............................................................................................................................. 195

Краткие итоги по главе 7.................................................................................................................................................. 202

Задания.................................................................................................................................................................................. 203

Глава 8. Наследование: проблемы и альтернативы. Интерфейсы. Композиция................................................... 204

Проблемы множественного наследования классов. Интерфейсы......................................................................... 204

Отличия интерфейсов от классов. Проблемы наследования интерфейсов........................................................ 206

Пример на использование интерфейсов....................................................................................................................... 208

Композиция как альтернатива множественному наследованию.......................................................................... 210

Краткие итоги по главе 8.................................................................................................................................................. 212

Задания.................................................................................................................................................................................. 212

Глава 9. Дополнительные элементы объектного программирования на языке Java........................................... 214

Потоки выполнения (threads) и синхронизация.......................................................................................................... 214

Преимущества и проблемы при работе с потоками выполнения.................................................................... 214

Синхронизация по ресурсам и событиям............................................................................................................... 215

Класс Thread и интерфейс Runnable. Создание и запуск потока выполнения............................................ 217

Поля и методы, заданные в классе Thread.............................................................................................................. 219

Подключение внешних библиотек DLL.“Родные” (native) методы*.................................................................... 221

Краткие итоги по главе 9.................................................................................................................................................. 224

Задания.................................................................................................................................................................................. 225

Глава 10. Введение в сетевое программирование.......................................................................................................... 227

Краткая справка по языку HTML................................................................................................................................... 227

Апплеты................................................................................................................................................................................. 232

Сервлеты................................................................................................................................................................................ 234

Технология JSP – Java Server Pages................................................................................................................................ 237

Краткие итоги по главе 10................................................................................................................................................ 241

Задания.................................................................................................................................................................................. 242

Глава 11. Встроенные классы.............................................................................................................................................. 243

Виды встроенных классов................................................................................................................................................ 243

Вложенные (nested) классы и интерфейсы................................................................................................................... 243

Внутренние (inner) классы................................................................................................................................................ 244

Локальные (local) классы.................................................................................................................................................. 246

Анонимные (anonimous) классы и обработчики событий....................................................................................... 246

Анонимные (anonimous) классы и слушатели событий (listeners)......................................................................... 247

Краткие итоги по главе 11................................................................................................................................................ 250

Задания.................................................................................................................................................................................. 251

Глава 12. Компонентное программирование................................................................................................................... 252

Компонентная архитектура JavaBeans........................................................................................................................ 252

Мастер создания компонента в NetBeans.................................................................................................................... 253

Пример создания компонента в NetBeans – панель с заголовком......................................................................... 256

Добавление в компонент новых свойств...................................................................................................................... 259

Добавление в компонент новых событий..................................................................................................................... 261

Краткие итоги по главе 12................................................................................................................................................ 265

Задания.................................................................................................................................................................................. 266

Литература................................................................................................................................................................................. 267

Дополнительная литература........................................................................................................................................... 267


Введение

Языку Java посвящены сотни тысяч книг и учебных курсов. Поэтому, без сомнения, предлагаемый курс может рассматриваться только как краткое введение в данную область. Его назначение – дать основные представления о концепциях языка и современном состоянии дел. Java быстро развивается, из-за чего многие прежние представления оказываются устаревшими.

Данный курс основан на лекциях, читавшихся автором студентам кафедры вычислительной физики физического факультета СПбГУ, но был существенно переработан. Курс рассчитан на широкую аудиторию начинающих программистов, от школьников-старшеклассников до студентов старших курсов, а также людей, желающих самостоятельно научиться программировать на этом языке. Кроме того, курс может быть интересен даже опытным программистам, которые по каким-либо причинам не отслеживали изменения и нововведения в Java за последние годы. Курс содержит информацию об основных синтаксических конструкциях языка Java, особенностях и типичных ошибках их использования, а также сведения о современных средах разработки.

Одной из привлекательных особенностей языка Java с самого начала была бесплатность распространения базовых средств разработки (SDK – Software Development Kit) и исполняющей среды Java (виртуальной Java-машины). Однако компилятор, входящий в состав SDK, работал в режиме командной строки, то есть отставал идеологически по крайней мере на 20 лет от современных профессиональных компиляторов. В 2006 году корпорация Sun Microsystems пошла на беспрецедентный шаг – сделала бесплатными профессиональные средства разработки программного обеспечения.

Еще одним шагом Sun в направлении открытости программного обеспечения, в том числе - исходного кода, стала разработка платформы NetBeans. Это среда, основанная на принципах компонентного программирования. Она включает в себя как среду разработки, так и набор библиотечных компонентов ( Beans – “зёрна”. Игра слов: язык Java получил название по имени кофе, которое любили программисты, так что название компонентной модели Java Beans может быть расшифровано как “зёрна кофе Java”). Компонентная модель NetBeans – дальнейший шаг после Java Beans.

Среда разработки NetBeans может быть свободно загружено с сайта Sun и распространяется на условиях лицензии Sun Public License (SPL). Данная лицензия подразумевает, что всё программное обеспечение, написанное на условиях SPL, поставляется с открытым исходным кодом (source code). В настоящее время продукт Sun Java Studio Enterprise прекратил самостоятельное существование и стал расширением среды NetBeans – теперь это NetBeans Enterprise Pack.

Все примеры, приводящиеся в данной книге, разработаны и проверены в среде NetBeans версии 5.5 с JDK1.5.0_04.

Упоминаемые в данной книге названия

Java ® и Solaris ® - являются торговыми марками корпорации Sun Microsystems

Windows® - является торговой маркой корпорации Microsoft

MacOS® - является торговой маркой корпорации Apple

Глава 1. Общие представления о языке Java

1.1. Java и другие языки программирования. Системное и прикладное программирование

Язык программирования Java был создан в рамках проекта корпорации Sun Microsystems по созданию компьютерных программно-аппаратных комплексов нового поколения. Первая версия языка была официально опубликована в 1995 году. С тех пор язык Java стал стандартом де-факто, вытеснив за десять лет языки C и C++ из многих областей программирования. В 1995 году они были абсолютными лидерами, но к 2006 году число программистов, использующих Java, стало заметно превышать число программистов, использующих C и C++, и составляет более четырёх с половиной миллионов человек. А число устройств, в которых используется Java, превышает полтора миллиарда.

Как связаны между собой языки C, C++, JavaScript и Java? Что между ними общего, и в чём они отличаются? В каких случаях следует, а в каких не следует их применять? Для того чтобы ответить на этот вопрос, следует сначала остановиться на особенностях программного обеспечения предыдущих поколений и о современных тенденциях в развитии программного обеспечения.

Первоначально программирование компьютеров шло в машинных кодах. Затем появились языки ASSEMBLER, которые заменили команды процессоров мнемоническими сокращениями, гораздо более удобными для человека, чем последовательности нулей и единиц. Их принято считать языками программирования низкого уровня (то есть близкими к аппаратному уровню), так как они ориентированы на особенности конкретных процессоров. Именно поэтому программы, написанные на языках ASSEMBLER, нельзя было переносить на компьютеры с другим типом процессора - процессоры имели несовместимые наборы команд. То есть они были непереносимы на уровне исходного кода (source code).

Программы, написанные в машинных кодах, то есть в виде последовательности ноликов и единиц, соответствующих командам процессора и необходимым для них данным, нет необходимости как-то преобразовывать. Их можно скопировать в нужное место памяти компьютера и передать управление первой команде программы (задать точку входа в программу).

Программы, написанные на каком-либо языке программирования, сначала надо перевести из одной формы (текстовой) в другую (двоичную, то есть в машинные коды). Процесс такого перевода называется трансляцией (от английского translation – “перевод”, “перемещение”). Не обязательно переводить программу из текстовой формы в двоичные коды, возможен процесс трансляции с одного языка программирования на другой. Или из кодов одного типа процессора в коды другого типа.

Имеется два основных вида трансляции – компиляция и интерпретация .

При компиляции первоначальный набор инструкций однократно переводится в исполняемую форму (машинные коды), и в последующем при работе программы используются только эти коды.

При интерпретации во время каждого вызова необходимых инструкций каждый раз сначала происходит перевод инструкций из одной формы (текстовой или двоичной) в другую – в исполняемые коды процессора используемого компьютера. И только потом эти коды исполняются. Естественно, что интерпретируемые коды исполняются медленнее, чем скомпилированные, так как перевод инструкций из одной формы в другую обычно занимает в несколько раз больше времени чем выполнение полученных инструкций. Но интерпретация обеспечивает большую гибкость по сравнению с компиляцией, и в ряде случаев без неё не обойтись.

В 1956 году появился язык FORTRAN – первый язык программирования высокого уровня (то есть не ориентированный на конкретную аппаратную реализацию компьютера). Он обеспечил переносимость программ на уровне исходных кодов, но довольно дорогой ценой. Во-первых, быстродействие программ, написанных на FORTRAN, было в несколько раз меньше, чем для ассемблерных. Во-вторых, эти программы занимали примерно в два раза больше места в памяти компьютера, чем ассемблерные. И, наконец, пришлось отказаться от поддержки особенностей периферийных устройств – общение с “внешним миром” пришлось ограничить простейшими возможностями, которые в программе одинаково реализовывались для ввода-вывода с помощью перфокарточного считывателя, клавиатуры, принтера, текстового дисплея и т.д. Тем не менее, языки программирования высокого уровня постепенно вытеснили языки ASSEMBLER, поскольку обеспечивали не только переносимость программ, но и гораздо более высокую их надёжность, а также несоизмеримо более высокую скорость разработки сложного программного обеспечения. FORTRAN до сих пор остаётся важнейшим языком программирования для высокопроизводительных численных научных расчётов.

Увеличение аппаратных возможностей компьютеров (количества памяти, быстродействия, появления дисковой памяти большого объёма), а также появление разнообразных периферийных устройств, привело к необходимости пересмотра того, как должны работать программы. Массовый выпуск компьютеров потребовал унификации доступа из программ к различным устройствам. Возникла идея, что из программы можно обращаться к устройству без учёта особенностей его аппаратной реализации. Это возможно, если обращение к устройству идёт не напрямую, а через прилагающуюся программу – драйвер устройства (по-английски driver означает “водитель”). Появились операционные системы - наборы драйверов и программ, распределяющих ресурсы компьютера между разными программами. Соответственно, программное обеспечение стало разделяться на системное и прикладное . Системное программное обеспечение – непосредственно обращающееся к аппаратуре, прикладное – решающее какие-либо прикладные задачи и использующее аппаратные возможности компьютера не напрямую, а через вызовы программ операционной системы. Прикладные программы стали приложениями операционной системы, или, сокращённо, приложениями (applications). Этот термин означает, что программа может работать только под управлением операционной системы. Если на том же компьютере установить другой тип операционной системы, программа-приложение первой операционной системы не будет работать.

Требования к прикладным программам принципиально отличаются от требований к системным программам. От системного программного обеспечения требуется максимальное быстродействие и минимальное количество занимаемых ресурсов, а также возможность доступа к любым необходимым аппаратным ресурсам. От прикладного – максимальная функциональность в конкретной предметной области. При этом быстродействие и занимаемые ресурсы не имеют значения до тех пор, пока не влияют на функциональность. Например, нет совершенно никакой разницы, реагирует программа на нажатие клавиши на клавиатуре за одну десятую или за одну миллионную долю секунды. Правда, на первоначальном этапе создания прикладного программного обеспечения даже прикладные по назначению программы были системными по реализации, так как оказывались вынуждены напрямую обращаться к аппаратуре.

Язык C был создан в 1972 году в одной из исследовательских групп Bell Laboratories при разработке операционной системы Unix. Сначала была предпринята попытка написать операционную систему на ASSEMBLER, но после появления в группе новых компьютеров пришлось создать платформонезависимый язык программирования высокого уровня, с помощью которого можно было бы писать операционные системы. Таким образом, язык 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++ имеется ещё два принципиальных недостатка: а) низкая надёжность как на уровне исходного кода, так и на уровне исполняемого кода; б) отсутствие переносимости на уровне исполняемого кода. С появлением компьютерных сетей эти недостатки стали очень существенным ограничивающим фактором, поскольку вопросы безопасности при работе в локальных, и, особенно, глобальных сетях приобретают первостепенную значимость.

В 1995 году появились сразу два языка программирования, имеющие в настоящее время огромное значение –Java, разработанный в корпорации Sun, и JavaScript, разработанный в небольшой фирме Netscape Communication, получившей к тому времени известность благодаря разработке браузера Netscape Navigator.

Java создавался как универсальный язык, предназначенный для прикладного программирования в неоднородных компьютерных сетях как со стороны клиентского компьютера, так и со стороны сервера. В том числе – для использования на тонких аппаратных клиентах (устройствах малой вычислительной мощности с крайне ограниченными ресурсами). При этом скомпилированные программы Java работают только под управлением виртуальной Java-машины, поэтому они называются приложениями Java . Синтаксис операторов Java практически полностью совпадает с синтаксисом языка C, но, в отличие от C++, Java не является расширением C – это совершенно независимый язык, со своими собственными синтаксическими правилами. Он является гораздо более сильно типизированным по сравнению с C и C++, то есть вносит гораздо больше ограничений на действия с переменными и величинами разных типов. Например, в C/C++ нет разницы между целочисленными числовыми, булевскими и символьными величинами, а также адресами в памяти. То есть, например, можно умножить символ на булевское значение, из которого вычтено целое число, и разделить результат на адрес! В Java введён вполне разумный запрет на почти все действия такого рода.

Язык JavaScript создавался как узкоспециализированный прикладной язык программирования HTML-страниц, расширяющий возможности HTML, и в полной мере отвечает этим потребностям до сих пор. Следует подчеркнуть, что язык JavaScript не имеет никакого отношения к Java. Включение слова “Java” в название JavaScript являлось рекламным трюком фирмы Netscape Communication. Он также C-образен, но, в отличие от Java, является интерпретируемым. Основное назначение JavaScript – программное управление элементами 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-компиляцией (Jast-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 компилятор gjc. Правда, заметные успехи Sun в усовершенствовании Java-машины позволили практически достичь, а в ряде случаев даже обогнать по быстродействию программы, написанные на других языках. В частности, приложения Java, активно занимающиеся выделением-высвобождением памяти, работают быстрее своих аналогов, написанных на C/C++, благодаря специальному механизму программных слотов памяти (slot – “паз, отверстие для вставления чего-либо”).

Виртуальная Java-машина не только исполняет байт-код (интерпретирует его, занимается JIT-компиляцией и исполняет JIT-компилированный код), но и выполняет ряд других функций. Например, взаимодействует с операционной системой, обеспечивая доступ к файлам или поддержку графики. А также обеспечивает автоматическое высвобождение памяти, занятой ненужными объектами – так называемую сборку мусора (garbage collection).

Программы Java можно разделить на несколько основных категорий:

· Приложение (application) – аналог “обычной” прикладной программы.

· Апплет (applet) – специализированная программа с ограниченными возможностями, работающая в окне WWW-документа под управлением браузера.

· Сервлет (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. Технология JSP заключается в наличии дополнительных конструкций в HTML- или XML-документах, которые позволяют осуществлять вызовы сценариев (“скриптов”), написанных на языке Java. В результате удаётся очень просто и удобно осуществлять обработку данных или элементов документа, и внедрять в нужные места документа результаты обработки. Сценарии Java перед первым выполнением автоматически компилируются на стороне сервера, поэтому выполняемый код выполняется достаточно быстро. Но, конечно, требует, чтобы была установлена соответствующая Java-машина. Например, входящая в состав Sun Application Server – программного обеспечения, обеспечивающего поддержку большого количества необходимых серверных возможностей для работы в WWW. Отметим, что Sun Application Server также распространяется бесплатно и входит в комплект NetBeans Enterprise Pack.

Первоначально Java позиционировался Sun как язык, обеспечивающий развитые графические возможности WWW-документов благодаря включению в них апплетов. Однако в настоящее время основными областями использования Java является прикладное программирование на основе приложений, страниц JSP и сервлетов, а также других видов серверных программ. При этом использование апплетов играет незначительную роль.

Виртуальную Java-машину часто называют исполняющей средой (Java Runtime Environment - JRE).

Существует два основных способа установки Java-машины на клиентский компьютер:

· JRE из поставки Software Development Kit (SDK) - Комплекта разработки программного обеспечения.

· Специализированный вариант JRE в составе Интернет-браузера, называющийся Java plugin.

Комплект последних версий SDK можно свободно загружать с сайта Sun http://java.sun.com/ .

При использовании апплетов требуется, чтобы в состав браузера входил специализированный комплект JRE. Как правило, он поставляется вместе с браузером, и может при необходимости обновляться. Для MS Internet Explorer такой комплект и его обновления могут быть свободно загружены с сайта Microsoft.

Имеется возможность установки Java-машины от различных производителей, не обязательно устанавливать комплект SDK от Sun. На одном и том же компьютере может быть установлено сразу несколько различных Java-машин, в том числе комплекты SDK разных версий. Правда, опыт показывает, что при этом некоторые программы, написанные на Java, теряют работоспособность (частично или полностью).

Комплекты SDK имеют классификацию, опирающуюся на версию Java (языка программирования и, соответственно, Java-машины) и тип создаваемых приложений. Так, ко времени написания данного текста выходили версии SDK 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 и 1.6. У каждой версии имеется ряд подверсий, не сопровождающихся изменением языка программирования, а связанных в основном с исправлением ошибок или внесением небольших изменений в библиотеки. Например, 1.4.1_01 или 1.5.0_04.

Версии Java 1.0 и 1.1 принято называть Java 1. Все версии Java начиная c 1.2 называют Java 2. Однако более надёжно классифицировать по номеру SDK, так как язык Java для версии SDK 1.5 очень заметно отличается по возможностям от языка Java для более ранних версий SDK – в него добавлено большое количество новых синтаксических конструкций, а также изменён ряд правил. Поэтому код, правильный в Java для версии SDK 1.5, может оказаться неправильным в Java для версии SDK 1.4. Не говоря уж про Java для версии SDK 1.3 или 1.2. Кроме того, недавно компания Sun перестала использовать в названиях комплектов программного обеспечения термин Java 2 и происходящие от него сокращения вида j2.

Комплекты разработки SDK одной версии отличаются по типу создаваемых с их помощью приложений. Имеется три типа SDK:

· Java ME – комплект Java Micro Edition (микро-издание) http://java.sun.com/j2me/, предназначенный для программирования “тонких аппаратных клиентов”. То есть устройств, обладающих малыми ресурсами - наладонных компьютеров, сотовых телефонов, микроконтроллеров, смарт-карт. Старое название J2ME.

· Java SE – комплект Java Standard Edition (стандартное издание) http://java.sun.com/j2se/, предназначенный для программирования “толстых клиентов”. То есть устройств, обладающих достаточно большими ресурсами - обычных компьютеров. Старое название J2SE.

· Java EE– комплект Java Enterprise Edition http://java.sun.com/j2ee/, предназначенный для написания серверного программного обеспечения. Старое название J2EE.

При распространении какого-либо продукта, написанного на Java, возможна установка только программного обеспечения Java-машины (JRE – Java Runtime Environment). Например, в случае использования Java 1.4.1_01 - комплекта j2re1.4.1_01. При этом создаётся папка с именем j2re1.4.1_01 с вложенными папками bin и lib. В папке bin содержатся файлы и папки, необходимые для работы Java-машины и дополнительных инструментов для работы с ней в специальных режимах. В папке lib содержатся вспомогательные файлы и библиотеки, в основном связанные с параметрами настроек системы.

Также возможна установка целиком SDK. Например, при установке SDK Java SE 1.5.0_04 создаётся папка JDK1.5.0_04 с вложенными папками bin, demo, include, jre, lib, sample, а также архивом src.zip с исходными кодами стандартных классов Java. В папке bin содержатся файлы инструментов разработки, в папке demo - файлы примеров с исходными кодами. В папке include - заголовки файлов C для доступа к ряду библиотек Java и отладчику виртуальной Java-машины на платформо-зависимом уровне - на основе интерфейсов JNI (Java Native Interface) и JVMDI (Java Virtual Machine Debugging Interface), соответственно. В папке jre находятся файлы, необходимые для работы с виртуальной Java-машиной. Папка lib содержит ряд библиотек и сопроводительных файлов, необходимых для работы инструментов из папки bin. В папке sample находятся примеры с исходными кодами.

Аббревиатура JDK расшифровывается как Java Development Kit – комплект разработки программного обеспечения на Java. К сожалению, в комплекте отсутствует даже самая простейшая документация с описанием назначения имеющихся в нём инструментов – даны ссылки на сайт компании Sun, где можно найти эту информацию. Поэтому перечислим назначение основных инструментов. Они делятся на несколько категорий.

Средства разработки приложений

Утилита

Назначение

javac

Компилятор в режиме командной строки для программ, написанных на языке Java

java

Утилита для запуска в режиме командной строки откомпилированных программ-приложений

appletviewer

Утилита для запуска на исполнение и отладку апплетов без браузера. При этом не гарантируется работоспособность отлаженного апплета в браузере.

jdb

Отладчик программ, написанных на языке Java

javadoc

Генератор документации по классом на основе комментариев, начинающихся с /**

jar

Создание и управление Java-архивами jar

javah

Генератор заголовочных файлов C/C++ для подключения к программам Java внешних библиотек C/C++ на основе интерфейса JNI

javap

Дизассемблер классов

extcheck

Утилита для обнаружения конфликтов между файлами архивов jar

native2ascii

Утилита для конвертации в режиме командной строки параметра, передаваемого в виде текста на национальном алфавите, в последовательность символов UNICODE.

Кроме этого, имеются средства поддержки работы в WWW и корпоративных сетях (интранет) с интерфейсом RMI - интерфейсом удалённого вызова методов. Это программы rmic, rmiregistry, rmid. Также имеются средства поддержки информационной безопасности keytool, jarsigner, policytool, и ряд файлов других категорий утилит.

Подчеркнём, что набор утилит JDK рассчитан на морально устаревший режим командной строки, и что гораздо удобнее и правильнее пользоваться современной профессиональной средой разработки NetBeans. Для её работы из JDK необходим только комплект JRE.

1.3.Алфавит языка Java. Десятичные и шестнадцатеричные цифры и целые числа. Зарезервированные слова

Алфавит языка Java

Алфавит языка Java состоит из букв, десятичных цифр и специальных символов. Буквами считаются латинские буквы (кодируются в стандарте ASCII), буквы национальных алфавитов (кодируются в стандарте Unicode, кодировка UTF-16), а также соответствующие им символы, кодируемые управляющими последовательностями (о них будет рассказано чуть позже).

Буквы и цифры можно использовать в качестве идентификаторов (т.е. имён) переменных, методов и других элементов языка программирования. Правда, при использовании в идентификаторах национальных алфавитов в ряде случаев могут возникнуть проблемы – эти символы будут показываться в виде вопросительных знаков.

Как буквы рассматривается только часть символов национальных алфавитов. Остальные символы национальных алфавитов - это специальные символы. Они используются в качестве операторов и разделителей языка Java и не могут входить в состав идентификаторов.

Латинские буквы ASCII

ABCD...XYZ - заглавные (прописные) ,

abcd...xyz – строчные

Дополнительные “буквы” ASCII

_ - знак подчеркивания,

$ - знак доллара.

Национальные буквы на примере русского алфавита

АБВГ…ЭЮЯ - заглавные (прописные),

абвг…эюя – строчные

Десятичные цифры

0 1 2 3 4 5 6 7 8 9

Десятичные и шестнадцатеричные цифры и целые числа

Целые числовые константы в исходном коде Java (так называемые литерные константы) могут быть десятичными или шестнадцатеричными. Они записываются либо символами ASCII, или символами Unicode следующим образом.

Десятичные константы записываются как обычно. Например, -137.

Шестнадцатеричная константа начинается с символов 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=5∙10+2, 137=1∙102 +3∙101 +7, и т.п.

В программировании десятичной системой счисления пользоваться не всегда удобно, так как в компьютерах информация организована в виде бит, байт и более крупных порций. Человеку неудобно оперировать данными в виде длинных последовательностей нулей и единиц. В настоящее время в программировании стандартной является шестнадцатеричная система записи чисел. Например, с её помощью естественным образом кодируется цвет, устанавливаются значения отдельных бит числа, осуществляется шифрование и дешифрование информации, и так далее. В этой системе счисления всё очень похоже на десятичную, но только не 10, а 16 цифр, и вес разряда не 10, а 16. В качестве первых 10 цифр используются обычные десятичные цифры, а в качестве недостающих цифр, больших 9, используются заглавные латинские буквы A, B, C, D, E, F:

0 1 2 3 4 5 6 7 8 9 A B C D E F

То есть A=10, B=11, C=12, D=13, E=14, F=15.

Заметим, что в шестнадцатеричной системе счисления числа от 0 до 9 записываются одинаково, а превышающие 9 отличаются. Для чисел от 10 до 15 в шестнадцатеричной системе счисления используются буквы от A до F, после чего происходит использование следующего шестнадцатеричного разряда. Десятичное число 16 в шестнадцатеричной системе счисления записывается как 10. Для того, чтобы не путать числа, записанные в разных системах счисления, около них справа пишут индекс с указанием основания системы счисления. Для десятичной системы счисления это 10, для шестнадцатеричной 16. Для десятичной системы основание обычно не указывают, если это не приводит к путанице. Точно так же в технической литературе часто не указывают основание для чисел, записанных в шестнадцатеричной системе счисления, если в записи числа встречаются не только “обычные” цифры от 0 до 9, но и “буквенные” цифры от A до F. Обычно используют заглавные буквы, но можно применять и строчные.

Рассмотрим примеры.

0x10 = 1016 =16 ;

0x100 = 10016 =16 ∙16=256;

0x1000 = 100016 =(16)3 =4096;

0x20 = 2016 =2∙16 =32;

0x21 = 2116 =2∙16 +1=33;

0xF = F16 =15 ;

0x1F = 1F16 =1∙16 +15=31 ;

0x2F = 2F16 =2∙16 +15=47 ;

0xFF = FF16 =15 ∙16+15=255;

Более подробно вопросы представления чисел в компьютере будут рассмотрены в отдельном разделе.

Зарезервированные слова языка Java

Это слова, зарезервированные для синтаксических конструкций языка, причём их назначение нельзя переопределять внутри программы.

abstract

boolean

break

byte

case

catch

char

class

const

continue

default

do

double

else

enum

extends

false

final

finally

float

for

goto

if

implements

import

instanceof

int

interface

long

native

new

null

package

private

protected

public

return

short

static

super

switch

synchronized

this

throw

throws

transient

true

try

void

volatile

while

Их нельзя использовать в качестве идентификаторов (имён переменных, подпрограмм и т.п.), но можно использовать в строковых выражениях.

1.4. Управляющие последовательности. Символы Unicode. Специальные символы

Управляющие последовательности

Управляющие последовательности - символы формирования текста

Иногда в тексте программы в строковых константах требуется использовать символы, которые обычным образом в текст программы ввести нельзя. Например, символы кавычек (их надо использовать внутри кавычек, что затруднительно), символ вопроса (зарезервирован для тернарного условного оператора), а также различные специальные символы. В этом случае используют управляющую последовательность – символ обратной косой черты, после которой следует один управляющий символ. В таблице приведены управляющие последовательности, применяющиеся в языке Java.

Символ

Что означает

\a

звонок

\b

возврат на один символ назад

\f

перевод на новую страницу

\n

перевод на новую строку

\r

возврат к началу строки

\t

горизонтальная табуляция

\v

вертикальная табуляция

\’

кавычка

\”

двойные кавычки

\\

обратная косая черта

\?

вопросительный знак

\u

начало кодировки символа Unicode

Управляющие последовательности – символы Unicode

Управляющая последовательность может содержать несколько символов. Например, символы национальных алфавитов могут кодироваться последовательностью “\u”, после которой идёт код символа в шестнадцатеричной кодировке для кодовых таблиц UTF-16 или UTF-8. Например:

\u0030 - \u0039 – цифры ISO-LATIN от 0 до 9

\u0024 – знак доллара $

\u0041 - \u005a – буквы от A до Z

\u0061 - \u007a – буквы от a до z

Простые специальные символы

+

Оператор сложения

.

Точка – десятичный разделитель в числовом литерном выражении; разделитель в составном имени для доступа к элементу пакета, класса, объекта, интерфейса

Оператор вычитания

(

Левая круглая скобка – используется для открытия списка параметров в операторах и для открытия группируемой части в выражениях

*

Оператор умножения

)

Правая круглая скобка– используется для закрытия списка параметров в операторах и для закрытия группируемой части в выражениях

/

Оператор деления

[

Левая квадратная скобка – открытие индекса массива

%

Оператор остатка от целочисленного деления

]

Правая квадратная скобка – закрытие индекса массива

=

Оператор присваивания

;

Точка с запятой – окончание оператора

~

Оператор побитового дополнения (побитовое “не”)

'

Апостроф (одиночная кавычка) – открытие и закрытие символа

?

Вопросительный знак – часть тернарного (состоящего из трёх частей) условного оператора “? :”

Двойные кавычки – открытие и закрытие строки символов

:

Двоеточие – часть условного оператора “? :”. Также используется для задания метки – ставится после имени метки.

\

обратная косая черта (backslash) – используется для задания управляющих последовательностей символов

^

Оператор “исключающее или” (XOR)

знак пробела (невидимый)

&

Оператор “побитовое и” (AND)

знак табуляции (невидимый)

|

Оператор “побитовое или” (OR)

@

Коммерческое a (“эт”) – знак начала метаданных

!

Оператор “НЕ”

#

- не имеет специального назначения

>

Больше

¤

- не имеет специального назначения

<

Меньше

«

- не имеет специального назначения

{

Левая фигурная скобка – открытие блока кода

»

- не имеет специального назначения

}

Правая фигурная скобка – закрытие блока кода

- не имеет специального назначения

,

Запятая - разделитель в списке параметров оператора; разделитель в составном операторе

§

- не имеет специального назначения

Составные специальные символы

Символ

Что означает

++

Оператор инкремента (увеличения на 1); x++ эквивалентно x=x+1

--

Оператор декремента (уменьшения на 1); x-- эквивалентно x=x-1

&&

Оператор “логическое И” (AND)

||

Оператор “ логическое ИЛИ” (OR)

<<

Оператор левого побитового сдвига

>>>

Оператор беззнакового правого побитового сдвига

>>

Оператор правого побитового сдвига с сохранением знака отрицательного числа

==

Равно

! =

не равно

+=

y+=x эквивалентно y=y+x

-=

y-=x эквивалентно y=y-x

*=

y*=x эквивалентно y=y*x

/=

y/=x эквивалентно y=y/x

%=

y%=x эквивалентно y=y%x

|=

y|=x эквивалентно y=y|x

^=

y^=x эквивалентно y=y^x

>>=

y>>=x эквивалентно y= y>>x

>>>=

y>>>=x эквивалентно y= y>>>x

<<=

y<<=x эквивалентно y= y<<x

/*

Начало многострочного комментария.

/**

Начало многострочного комментария, предназначенного для автоматического создания документации по классу.

*/

Конец многострочного комментария (открываемого как /* или /**).

//

Однострочный комментарий.

1.5.Идентификаторы. Переменные и типы . Примитивные и ссылочные типы

Идентификаторы - это имена переменных, подпрограмм-функций и других элементов языка программирования. В идентификаторах можно применять только буквы и цифры, причём первой всегда должна быть буква (в том числе символы подчёркивания и доллара), а далее может идти произвольная комбинация букв и цифр. Некоторые символы национальных алфавитов рассматриваются как буквы, и их можно применять в идентификаторах. Но некоторые используются в качестве символов-разделителей, и в идентификаторах их использовать нельзя.

Язык Java является регистро-чувствительным . Это значит, что идентификаторы чувствительны к тому, в каком регистре (верхнем или нижнем) набираются символы. Например, имена i1 и I1 соответствуют разным идентификаторам. Это правило привычно для тех, кто изучал языки C/C++, но может на первых порах вызвать сложности у тех, кто изучал язык PASCAL, который является регистро-нечувствительным.

Длина идентификатора в Java любая, по крайней мере, в пределах разумного. Так, даже при длине идентификатора во всю ширину экрана компилятор NetBeans правильно работает.

Переменная – это именованная ячейка памяти, содержимое которой может изменяться. Перед тем, как использовать какую-либо переменную, она должна быть задана в области программы, предшествующей месту, где эта переменная используется. При объявлении переменной сначала указывается тип переменной, а затем идентификатор задаваемой переменной. Указание типа позволяет компилятору задавать размер ячейки (объём памяти, выделяемой под переменную или значение данного типа), а также допустимые правила действий с переменными и значениями этого типа. В Java существует ряд предопределённых типов: int – целое число, float – вещественное число, boolean – логическое значение, Object – самый простой объектный тип (класс) Java, и т.д. Также имеется возможность задавать собственные объектные типы (классы), о чём будет рассказано позже.

Объявление переменных a1 и b1, имеющих некий тип MyType1, осуществляется так:

MyType1 a1,b1;

При этом MyType1 – имя типа этих переменных.

Другой пример – объявление переменной j типа int :

int j;

Типы бывают предопределённые и пользовательские. Например, int – предопределённый тип, а MyType1– пользовательский. Для объявления переменной не требуется никакого зарезервированного слова, а имя типа пишется перед именами задаваемых переменных.

Объявление переменных может сопровождаться их инициализацией - присваиванием начальных значений. Приведём пример такого объявления целочисленных переменных i1 и i2 :

int i1=5;

int i2=-78;

либо

int i1=5,i2=-78;

Присваивания вида int i1=i2=5;, характерные для C/C++, запрещены.

Для начинающих программистов отметим, что символ “=” используется в Java и многих других языках в качестве символа присваивания , а не символа равенства, как это принято в математике. Он означает, что значение, стоящее с правой стороны от этого символа, копируется в переменную, стоящую в левой части. То есть, например, присваивание b =a означает, что в переменную (ячейку) с именем b надо скопировать значение из переменной (ячейки) с именем a . Поэтому неправильное с точки зрения математики выражение

x=x+1

в программировании вполне корректно. Оно означает, что надо взять значение, хранящееся в ячейке с именем x , прибавить к нему 1 (это будет происходить где-то вне ячейки x ), после чего получившийся результат записать в ячейку x , заменив им прежнее значение.

После объявления переменных они могут быть использованы в выражениях и присваиваниях:

переменная=значение;

переменная=выражение;

переменная1= переменная2;

и так далее. Например,

i1=i2+5*i1;

Примитивными типами называются такие, для которых данные содержатся в одной ячейке памяти, и эта ячейка не имеет подъячеек.

Ссылочными типами называются такие, для которых в ячейке памяти (ссылочной переменной ) содержатся не сами данные, а только адреса этих данных, то есть ссылки на данные. При присваивании в ссылочную переменную заносится новый адрес, а не сами данные. Но непосредственного доступа к адресу, хранящемуся в ссылочных переменных, нет. Это сделано для обеспечения безопасности работы с данными – как с точки зрения устранения непреднамеренных ошибок, характерных для работы с данными по их адресам в языках C/C++/PASCAL, так и для устранения возможности намеренного взлома информации.

Если ссылочной переменной не присвоено ссылки, в ней хранится нулевой адрес, которому дано символическое имя null. Ссылки можно присваивать друг другу, если они совместимы по типам, а также присваивать значение null. При этом из одной ссылочной переменной в другую копируется адрес. Ссылочные переменные можно сравнивать на равенство, в том числе на равенство null. При этом сравниваются не данные, а их адреса, хранящиеся в ссылочных переменных.

В Java все типы делятся на примитивные и ссылочные. К примитивным типам относятся следующие предопределённые типы: целочисленные типы byte,short,int, long, char, типы данных в формате с плавающей точкой float, double, а также булевский (логический) тип boolean и типы-перечисления, объявляемые с помощью зарезервированного слова enum (сокращение от enumeration – “перечисление”). Все остальные типы Java являются ссылочными.

В Java действуют следующие соглашения о регистре букв в идентификаторах:

· Имена примитивных типов следует писать в нижнем регистре (строчными буквами). Например, int, float, boolean и т.д.

· Имена ссылочных типов следует начинать с заглавной (большой) буквы, а далее для имён, состоящих из одного слова, писать все остальные буквы в нижнем регистре. Например, Object, Float, Boolean, Collection, Runnable. Но если имя составное, новую часть имени начинают с заглавной буквы. Например, JButton, JTextField, JFormattedTextField, MyType и т.д. Обратите внимание, что типы float и Float, boolean и Boolean различны – язык Java чувствителен к регистру букв!

· Для переменных и методов имена, состоящие из одного слова, следует писать в нижнем регистре. Например, i, j, object1. Если имя составное, новую часть имени начинают с заглавной буквы: myVariable, jButton2, jTextField2.getText() и т.д.

· Имена констант следует писать в верхнем регистре (большими буквами), разделяя входящие в имя составные части символом подчёркивания “_”. Например, Double.MIN_VALUE, Double.MAX_VALUE , JOptionPane.INFORMATION_MESSAGE, MY_CHARS_COUNT и т.п.

· Символ подчёркивания “_” рекомендуется использовать для разделения составных частей имени только в именах констант и пакетов.

Переменная примитивного типа может быть отождествлена с ячейкой, в которой хранятся данные. У неё всегда есть имя. Присваивание переменной примитивного типа меняет значение данных. Для ссылочных переменных действия производятся с адресами ячеек, в которых хранятся данные, а не с самими данными.

Для чего нужны такие усложнения? Ведь человеку гораздо естественнее работать с ячейками памяти, в которых хранятся данные, а не адреса этих данных. Ответ заключается в том, что в программах часто требуются динамически создаваемые и уничтожаемые данные. Для них нельзя заранее создать необходимое число переменных, так как это число неизвестно на этапе написания программы и зависит от выбора пользователя. Такие данные приходится помещать в динамически создаваемые и уничтожаемые ячейки. А с этими ячейками удаётся работать только с помощью ссылочных переменных.

Ссылочные типы Java используются в объектном программировании. В частности, для работы со строками, файлами, элементами пользовательского интерфейса. Все пользовательские типы (задаваемые программистом) , кроме типов-перечислений, являются ссылочными. В том числе – строковые типы.


Краткие итоги по главе 1

- Алфавит языка Java состоит из букв, десятичных цифр и специальных символов. Буквами считаются латинские буквы (кодируются в стандарте ASCII), буквы национальных алфавитов (кодируются в стандарте Unicode), а также соответствующие им символы, кодируемые управляющими последовательностями.

- В программах разрешается пользоваться десятичными и шестнадцатеричными целыми числовыми константами. Шестнадцатеричная константа начинается с символов 0x или 0X, после чего идёт само число в шестнадцатеричной нотации.

- Java - универсальный язык прикладного программирования, JavaScript – узкоспециализированный язык программирования HTML-документов, C++ - универсальный язык системного программирования. Java - компилируемый, платформонезависимый, объектно-ориентированный язык с C-образным синтаксисом.

- Программы Java переносимы как на уровне исходных кодов, так и на уровне скомпилированных исполняемых кодов – байт-кода. Байт-код является платформонезависимым, так как не содержит инструкций процессора конкретного компьютера. Он интерпретируется виртуальной Java-машиной (JVM).

- JIT-компиляция (Jast-In-Time) – компиляция байт-кода в код конкретной платформы в момент выполнения программы, то есть “по ходу дела”, “налету”. Она позволяет ускорить работу программ за счёт замены интерпретации байт-кода на выполнение скомпилированного кода.

- Основные категории программ Java:

· Приложение (application) – аналог “обычной” прикладной программы.

· Апплет (applet) – специализированная программа, работающая в окне WWW-документа под управлением браузера.

· Сервлет (servlet) - специализированная программа, работающая в WWW на стороне сервера

· Модуль EJB (Enterprise JavaBeans) – предназначен для многократного использования серверными приложениями Java

· Библиотека – предназначена для многократного использования программами классов Java

- Версии Java 1.0 и 1.1 принято называть Java 1. Все версии Java начиная c 1.2 принято называть Java 2.

- Поставить на компьютер исполняющую среду Java (виртуальную Java-машину) можно путём установки SDK (Software Development Kit) - Комплекта разработки программного обеспечения. Имеется три типа SDK:

· Java ME – комплект Java Micro Edition, предназначенный для программирования “тонких аппаратных клиентов”.

· Java SE – комплект Java Standard Edition, предназначенный для программирования обычных компьютеров.

· Java EE– комплект Java Enterprise Edition, предназначенный для написания серверного программного обеспечения.

- Язык Java является регистро-чувствительным. Исходные коды программ Java набираются в виде последовательности символов Unicode.

- Управляющая последовательность применяется в случае, когда требуется использовать символ, который обычным образом в текст программы ввести нельзя. Простая управляющая последовательность начинается с символа “\”, после которого идёт управляющий символ. Управляющая последовательность для кодирования символа Unicode начинается с последовательности из двух символов -“\u”, после которой следует четыре цифры номера символа в шестнадцатеричной нотации. Например, \u1234 .

- Специальные символы используются в качестве операторов и разделителей языка Java и не могут входить в состав идентификаторов. Специальные символы бывают простые и составные. Они используются в операторах, для форматирования текста и как разделители.

- Идентификаторы - это имена переменных, процедур, функций и т.д. В идентификаторах можно применять только буквы и цифры, причём первой всегда должна быть буква, а далее может идти произвольная комбинация букв и цифр. Длина идентификатора в Java любая.

- Переменная – это именованная ячейка памяти, содержимое которой может изменяться. При объявлении переменной сначала указывается тип переменной, а затем идентификатор задаваемой переменной.

- Типы в Java делятся на примитивные и ссылочные. Существует несколько предопределённых примитивных типов, все остальные – ссылочные. Все пользовательские типы кроме типов-перечислений являются ссылочными. Значение null соответствует ссылочной переменной, которой не назначен адрес ячейки с данными.

Типичные ошибки:

- Путают языки Java и JavaScript, либо считают, что JavaScript – это интерпретируемый вариант Java. Хотя эти языки не имеют друг к другу никакого отношения.

- Ошибочно считают, что приложение Java может быть запущено на любом компьютере без установки исполняющей среды (JRE).

- Не различают приложения (applications) и апплеты (applets).

- При записи шестнадцатеричного числа вида 0x… вместо ведущего нуля пишут букву O.

- Ошибочно считают, что в идентификаторах Java нельзя использовать символы национальных алфавитов.

- Ошибочно считают, что не имеет значения, в каком регистре набраны символы идентификатора (характерно для тех, кто раньше программировал на PASCAL или FORTRAN).

Задания

· Написать в 16-ричном виде числа 0, 1, 8, 15, 16, 255, 256.

· Дать ответ, являются ли допустимыми идентификаторами i1, i_1, 1i, i&1, i1234567891011, IJKLMN ?

· Являются ли допустимыми и различными идентификаторы myObject, MyObject, myobject, Myobject, my object, my_object ?

Глава 2. Объектно-ориентированное проектирование и плат форма NetBeans

2.1.Процедурное и объектно-ориентированное программирование. Инкапсуляция

Объектно-ориентированное программирование (ООП) - это методология программирования, опирающаяся на три базовых принципа:

- инкапсуляцию ,

- наследование ,

- полиморфизм .

Язык Java является объектно-ориентированным и в полном объёме использует эти принципы. В данном параграфе рассматривается принцип инкапсуляции, наследованию и полиморфизму посвящены отдельные параграфы.

Построение программ, основанных на ООП, принципиально отличается от более ранней методики процедурного программирования , в которой основой построения программы служили подпрограммы .

Программа – это набор инструкций процессору и данных, объединённых в единую функционально законченную последовательность, позволяющую выполнять какую-нибудь конкретную деятельность.

Подпрограмма – это набор инструкций и данных, объединённых в относительно самостоятельную последовательность, позволяющую выполнять какую-нибудь конкретную деятельность внутри программы. При этом подпрограмма не может работать самостоятельно - она запускается из программы, и может получать из неё данные или передавать их в программу.

Подпрограммы принято делить на подпрограммы-процедуры и подпрограммы-функции. Подпрограммы-процедуры вызываются для выполнения каких-либо действий, например – распечатки текста на принтере. Подпрограммы-функции выполняют какие-либо действия и возвращают некоторое значение. Например, проводится последовательность действий по вычислению синуса, и возвращается вычисленное значение. Или создаётся сложно устроенный объект и возвращается ссылка на него (адрес ячейки, в которой он находится).

Программы, написанные в соответствии с принципами процедурного программирования, состоят из набора подпрограмм, причём для решения конкретной задачи программист явно указывает на каждом шагу, что делать и как делать. Эти программы практически полностью (процентов на девяносто) состоят из решения конкретных задач.

Программы, написанные в соответствии с принципами ООП, пишутся совершенно иначе. В них основное время занимает продумывание и описание того, как устроены классы. Код с описанием классов предназначен для многократного использования без внесения каких-либо изменений. И только небольшая часть времени посвящается решению конкретной задачи – написания такого кода с использованием классов, который в других задачах такого типа не применить. Именно благодаря такому подходу объектное программирование приобрело огромную популярность – при необходимости решения сходных задач можно использовать уже готовый код, модифицировав только ту часть программы, которая относится к решению конкретной задачи.

Подробный разбор принципов ООП будет дан позже. Пока же в общих чертах разъясним их суть.

Самым простым из указанных в начале параграфа принципов является инкапсуляция . Это слово в общем случае означает “заключение внутрь капсулы”. То есть ограничение доступа к внутреннему содержимому снаружи и отсутствие такого ограничения внутри капсулы. В объектном программировании “инкапсуляция” означает использование классов – таких типов , в которых кроме данных описаны подпрограммы, позволяющие работать с этими данными, а также выполнять другие действия. Такие подпрограммы, инкапсулированные в класс, называются методами . Поля данных и методы, заданные в классе, часто называют членами класса (class members).

Класс – это описание того, как будет устроен объект , являющийся экземпляром данного класса , а также какие методы объект может вызывать. Заметим, что методы, в отличие от других подпрограмм, могут напрямую обращаться к данным своего объекта. Так как экземплярами классов (“воплощением” в реальность того, что описано в классе) являются объекты, классы называют объектными типами .

Все объекты, являющиеся экземплярами некоторого класса, имеют одинаковые наборы полей данных (атрибуты объекта) – но со значениями этих данных, которые свои для каждого объекта. Поля данных это переменные, заданные на уровне описания класса, а не при описании метода. В процессе жизни объекта эти значения могут изменяться. Значения полей данных объекта задают его состояние . А методы задают поведение объекта. Причём в общем случае на это поведение влияет состояние объекта – методы пользуются значениями его полей данных.

Классы в Java задаются следующим образом. Сначала пишется зарезервированное слово class, затем имя класса, после чего в фигурных скобках пишется реализация класса – задаются его поля (глобальные переменные ) и методы.

Объектные переменные – такие переменные, которые имеют объектный тип. В Java объектные переменные – это не сами объекты, а только ссылки на них. То есть все объектные типы являются ссылочными.

Объявление объектной переменной осуществляется так же, как и для других типов переменных. Сначала пишется тип, а затем через пробел имя объявляемой переменной.

Например, если мы задаём переменную obj1 типа Circle, “окружность”, её задание осуществляется так :

Circle obj1;

Связывание объектной переменной с объектом осуществляется путём присваивания. В правой части присваивания можно указать либо функцию, возвращающую ссылку на объект (адрес объекта), либо имя другой объектной переменной. Если объектной переменной не присвоено ссылки, в ней хранится значение null. Объектные переменные можно сравнивать на равенство, в том числе на равенство null. При этом сравниваются не сами объекты, а их адреса, хранящиеся в объектных переменных.

Создаётся объект с помощью вызова специальной подпрограммы, задаваемой в классе и называемой конструктором . Конструктор возвращает ссылку на созданный объект. Имя конструктора в Java всегда совпадает с именем класса , экземпляр которого создаётся. Перед именем конструктора во время вызова ставится оператор new – “новый”, означающий, что создаётся новый объект. Например, вызов

obj1=new Circle();

означает, что создаётся новый объект типа Circle, “окружность”, и ссылка на него (адрес объекта) записывается в переменную obj1. Переменная obj1 до этого уже должна быть объявлена. Оператор new отвечает за динамическое выделение памяти под создаваемый объект.

Часто совмещают задание объектной переменной и назначение ей объекта. В нашем случае оно будет выглядеть как

Circle obj1=new Circle();

У конструктора, как и у любой подпрограммы, может быть список параметров. Они нужны для того, чтобы задать начальное состояние объекта при его создании. Например, мы хотим, чтобы у создаваемой окружности можно было при вызове конструктора задать координаты x, y её центра и радиус r. Тогда при написании класса Circle можно предусмотреть конструктор, в котором первым параметром задаётся координата x, вторым – y, третьим – радиус окружности r. Тогда задание переменной obj1 может выглядеть так:

Circle obj1=new Circle(130,120,50);

Оно означает, что создаётся объект-окружность, имеющий центр в точке с координатами x=130, y=120, и у которой радиус r=50.

Если разработчики класса не создали ни одного конструктора, в реализации класса автоматически создаётся конструктор по умолчанию, имеющий пустой список параметров. И его можно вызывать в программе так, как мы это первоначально делали для класса Circle.

Отметим ещё одно правило, касающееся используемых имён. Как мы помним, имена объектных типов принято писать с заглавной буквы, а имена объектных переменных – с маленькой. Если объектная переменная имеет тип Circle, она служит ссылкой на объекты-окружности. Поэтому имя obj1 не очень удачно – мы используем его только для того, чтобы подчеркнуть, что именно с помощью этой переменной осуществляется связь с объектом, и чтобы читатель не путал тип переменной, её имя и имя конструктора. В Java принято называть объектные переменные так же, как их типы, но начинать имя со строчной буквы. Поэтому предыдущий оператор мог бы выглядеть так:

Circle circle=new Circle(130,120,50);

Если требуется работа с несколькими объектными переменными одного типа, их принято называть в соответствии с указанным выше правилом, но добавлять порядковый номер. Следующие строки программного кода создают два независимых объекта с одинаковыми начальными параметрами:

Circle circle1=new Circle(130,120,50);

Circle circle2=new Circle(130,120,50);

С помощью объектных переменных осуществляется доступ к полям данных или методам объекта: сначала указывается имя переменной, затем точка, после чего пишется имя поля данных или метода. Например, если имя объектной переменной obj1, а имя целочисленного поля данных x, то присваивание ему нового значения будет выглядеть как

obj1.x=5;

А если имя подпрограммы show, у неё нет параметров и она не возвращает никакого значения, то её вызов будет выглядеть как

obj1.show();

Методы делятся на методы объектов и методы классов . Чаще всего пользуются методами объектов. Они так называются потому, что пользуются полями данных объектов, и поэтому их можно вызывать только из самих объектов. Методы классов, напротив, не пользуются полями данных объектов, и могут работать при отсутствии объекта. Поэтому их можно вызывать как из классов, так и из объектов. Формат вызова: имяКласса.имяМетода(список параметров) или имяОбъекта. имяМетода(список параметров) .

При задании метода класса перед его именем необходимо поставить модификатор static – “статический”. Это крайне неудачное название, пришедшее в язык Java из C++. Мы никогда не будем называть такие методы статическими, а будем называть их методами класса, как это принято в теории программирования.

Точно так же переменные (поля данных) делятся на переменные объектов и переменные классов . При задании переменной класса перед её именем необходимо поставить модификатор static. Переменные класса, как и методы класса, можно вызывать как из классов, так и из объектов. Формат вызова: имяКласса.имяПеременной или имяОбъекта.имяПеременной .

Не следует путать классы, объекты и объектные переменные. Класс – это тип, то есть описание того, как устроена ячейка памяти, в которой будут располагаться поля данных объекта. Объект – это содержимое данной ячейки памяти. А в переменной объектного типа содержится адрес объекта, то есть адрес ячейки памяти. Сказанное относится только к языкам с динамической объектной моделью, каким, в частности, является Java. В C++ это не так.

Как уже было сказано, кроме полей данных в классе описываются методы. Несмотря на схожесть задания в классе полей и методов их реальное размещение во время работы программы отличается. Методы не хранятся в объектах, но объекты могут их вызывать. Каждый объект имеет свой комплект полей данных – “носит свои данные с собой”. Если имеется сотня объектов одного типа, то есть являющихся экземплярами одного и того же класса, в памяти компьютера будет иметься сотня ячеек памяти, устроенных так, как это описано в классе. Причём у каждого объекта значения этих данных могут быть свои. Например, если объект является окружностью, отрисовываемой на экране, у каждой окружности будет свой набор координат, радиусов и цветов. Если мы будем отрисовывать окружности с помощью метода show(), нет необходимости в каждом объекте хранить код этого метода – он для всех ста объектов будет одним и тем же. Поэтому методы не хранятся в объектах – они хранятся в классах. Класс – более общая сущность, чем объект, и до того, как во время работы программы в памяти компьютера будет создан объект, сначала должен быть загружен в память соответствующий ему класс. В Java имеется возможность создавать переменные типа “класс”, и с их помощью обращаться к классам таким образом, как будто это объекты особого рода. Но, в отличие от обычных объектов, такие “объекты” не могут существовать в нескольких экземплярах, и правила работы с ними принципиально отличаются от работы с объектами. Такие сущности называются метаобъектами .

Объявление переменных может осуществляться либо в классе, либо в методе. В первом случае мы будем говорить, что переменная является полем данных объекта, или глобальной переменной. Во втором – что она является локаль ной переменной.

2.2. Работа со ссылочными переменными. Сборка мусора

Объекты, как мы уже знаем, являются экземплярами ссылочных типов. Работа со ссылочными переменными имеет специфику, принципиально отличающую её от работы с переменными примитивного типа. В каждой переменной примитивного типа содержится своё значение, и изменение этого значения не влияет на те значения, которые можно получить с помощью других переменных. Причём имя переменной примитивного типа можно рассматривать как имя ячейки с данными, и у такой ячейки может быть только одно имя, которое не может меняться по ходу работы программы. Для ссылочных переменных это не так.

Переменные ссылочного типа содержат адреса данных, а не сами данные. Поэтому присваивания для таких переменных меняют адреса, но не данные. Кроме того, из-за этого под них выделяется одинаковое количество памяти независимо от типа объектов, на которые они ссылаются. А имена ссылочных переменных можно рассматривать как псевдонимы имён ячеек с данными – у одной и той же ячейки с данными может быть сколько угодно псевдонимов, так как адрес одной и той же ячейки можно копировать в произвольное число переменных соответствующего типа. И все они будут ссылаться на одну и ту же ячейку с данными.

В Java ссылочные переменные используются для работы с объектами: в этом языке программирования используется динамическая объектная модель , и все объекты создаются динамически, с явным указанием в программе момента их создания. Это отличает Java от C++, языка со статической объектной моделью . В C++ могут существовать как статически заданные объекты, так и динамически создаваемые. Но это не преимущество, как могло бы показаться, а проблема, так как в ряде случаев создаёт принципиально неразрешимые ситуации.

Следует отметить, что сами объекты безымянны, и доступ к ним осуществляется только через ссылочные переменные. Часто говорят про ссылочную переменную как про сам объект, поскольку долго и неудобно произносить “объект, на который ссылается данная переменная”. Но этого по мере возможности следует избегать.

Ссылочной переменной любого типа может быть присвоено значение null, означающее, что она никуда не ссылается. Попытка доступа к объекту через такую переменную вызовет ошибку. В Java все ссылочные переменные первоначально инициируются значением null, если им не назначена ссылка на объект прямо в месте объявления. Очень часто встречающаяся ошибка – попытка доступа к полю или методу с помощью ссылочной переменной, которой не сопоставлен объект. Такая ошибка не может быть обнаружена на этапе компиляции и является ошибкой времени выполнения (Run-time error). При этом приложение Java генерирует исключительную ситуацию (ошибку) попытки доступа к объекту через ссылку null с сообщением следующего вида:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException.

Последовательность действий со ссылочными переменными и объектами удобно описывать с помощью рисунков, на которых каждой такой переменной и каждому объекту сопоставлен прямоугольник – символическое изображение ячейки. Около ячейки пишется её имя, если оно есть, а внутри – значение, содержащееся в ячейке.

Объект


Ссылочная переменная

Если переменная является ссылочной, из неё выходит стрелочка-ссылка. Она кончается на том объекте, на который указывает ссылка. Если в ссылочной переменной содержится значение null (ссылка “в никуда”, адрес==0), рисуется “висящая” короткая стрелка, у которой находится надпись “null”. Отметим, что в Java символом равенства является “==”, а не символ “=”, который используется для оператора присваивания.

Если ссылка перещёлкивается, то либо создаётся новый рисунок (в книжке), либо перечёркивается крестиком прежняя стрелочка и рисуется новая (на листе бумаги или на доске). При новом перещёлкивании эта “старая” стрелка перечёркивается двумя крестиками, а “более свежая”, которая была перещёлкнута – одним крестиком, и так далее. Такая система обозначений позволяет наглядно представить, что происходит при работе со ссылками, и не запутаться в том, куда они указывают и с какими ссылками в какой момент связаны динамически создаваемые объекты.

При выполнении оператора new , после которого указан вызов конструктора, динамически выделяется новая безымянная ячейка памяти, имеющая тип, соответствующий типу конструктора, а сам конструктор после окончания работы возвращает адрес этой ячейки. Если у нас в левой части присваивания стоит ссылочная переменная, то в результате ссылка “перещёлкивается” на динамически созданную ячейку.

Рассмотрим этот процесс подробнее. Будем считать, что сначала в ячейке circle1 типа Circle хранится нулевой адрес (значение ссылки равно null). Будем изображать это как стрелку в никуда с надписью null.

Переменная

circle1 типа Circle


null

После оператора

circle1=new Circle(x1,y1,r1) ;

в динамически выделенной безымянной ячейке памяти будет создан объект-окружность с координатами центра x1, y1 и радиусом r1 (это какие-то значения, конкретная величина которых в данном случае не имеет значения):

Объект1 типа Circle


circle1

Адрес


Поля объекта доступны через ссылку как по чтению, так и по записи. До тех пор, пока ссылочная переменная circle1 содержит адрес Объекта1, имя circle1 является псевдонимом, заменяющим имя этого объекта. Его можно использовать так же, как имя обычной переменной в любых выражениях и операторах, не связанных с изменением адреса в переменной circle1.

Поскольку между ссылочными переменными одного типа разрешены присваивания, переменная по ходу программы может сменить объект, на который она ссылается. Если circle2 также имеет тип Circle, то допустимы присваивания вида

circle2= circle1;

Такие присваивания изменяют адреса в ячейках ссылочных переменных, но не меняют содержания объектов.

Рассмотрим следующий участок кода:

Circle circle1=new Circle(x1,y1,r1) ;

Circle circle2=new Circle(x2,y2,r2) ;

Circle circle3;

Ему соответствует следующий рисунок:

Объект1 типа Circle


circle1

Адрес1

Объект2 типа Circle


circle2

Адрес2


circle3

Адрес==0


null

Проведём присваивание

circle3=circle2;

В результате получится такая картинка:

Объект1 типа Circle


circle1

Адрес1

Объект2 типа Circle


circle2

Адрес2


circle3

Адрес2


Обе переменные, как circle2, так и circle3, теперь ссылаются на один и тот же объект – в них находится один и тот же Адрес2. То есть оба имени – синоним имени Объекта2. Напомним, что сам объект, как все динамически создаваемые величины, безымянный. Таким образом, circle2.x даст значение x2, точно так же, как и circle3.x. Более того, если мы изменим значение circle2.x, это приведёт к изменению circle3.x – ведь это одно и то же поле x нашего Объекта2.

Рассмотрим теперь, что произойдёт при присваивании

circle1=circle2;

Этот случай отличается от предыдущего только тем, что переменная circle1 до присваивания уже была связана с объектом.

Объект1 типа Circle

x==x1

y==y1

r==r1


circle1

Адрес2

Объект2 типа Circle


circle2

Адрес2


circle3

Адрес2


В результате у Объекта2 окажется сразу три ссылочные переменные, которые с ним связаны, и имена которых являются его псевдонимами в данном месте программы: circle1, circle2 и circle3. При этом программная связь с Объектом1 окажется утеряна – он занимает место в памяти компьютера, но программный доступ к нему невозможен, поскольку адрес этого объекта программой утерян. Таким образом, он является бесполезным и напрасно занимает ресурсы компьютера.

Про такие ячейки памяти говорят, что они являются мусором . В Java предусмотрен механизм высвобождения памяти, занятой такими бесполезными объектами. Он называется сборкой мусора (garbage collection) и работает автоматически. Этим в фоновом режиме занимается специальная часть виртуальной Java-машины, сборщик мусора . При программировании на Java, отличие от таких языков как C/C++ или Object PASCAL, программисту нет необходимости самому заботиться о высвобождении памяти, занятой под динамически создаваемые объекты.

Следует подчеркнуть, что намеренная потеря связи ссылочной переменной с ненужным уже объектом – это одно, а непреднамеренная – совсем другое. Если вы не планировали потерю связи с объектом, а она произошла, это логическая ошибка. И хотя она не приведёт к зависанию программы или её неожиданному закрытию, такая программа будет работать не так, как вы предполагали, то есть неправильно или не совсем правильно. Что иногда ещё опасней, так как ошибку можно не заметить или, если заметили, очень трудно понять её причину.

2.3. Проекты NetBeans. Пакеты. Уровни видимости классов. Импорт классов

Современное программное обеспечение построено по модульному (блочному) принципу. Программы давно перестали состоять из одного файла. Поэтому вместо слова “программа” лучше употреблять слово “проект”. Тем более что термин “программа”, как уже говорилось, неоднозначен.

Идеология Java подразумевает работу в компьютерных сетях и возможность подгрузки в необходимый момент через сеть требуемых классов и ресурсов, в которых нуждается программа, и которые не были до того загружены. Для обеспечения такого рода работы приложения Java разрабатываются и распространяются в виде большого числа независимых классов. Однако такой способ разработки приводит к чрезвычайно высокой фрагментации программы. Даже небольшие учебные проекты часто состоят из десятков классов, а реальные проекты – из сотен. При этом каждому общедоступному (public) классу соответствует свой файл, имеющий то же имя. Для того чтобы справиться с таким обилием файлов, в Java предусмотрено специальное средство группировки классов, называемое пакетом (package). Пакеты обеспечивают независимые пространства имён (namespaces), а также ограничение доступа к классам.

Классы всегда задаются в каком-либо пакете. Пакеты могут быть вложенными с произвольным уровнем вложения (ограничивается только операционной системой и, как правило, не менее 256). Каждому пакету соответствует папка с исходными кодами соответствующих классов, при этом пакету, вложенному в другой, соответствует папка, вложенная в другую.

Для того чтобы поместить класс в пакет, требуется продекларировать имя пакета в начале файла, в котором объявлен класс, в виде

package имя_пакета;

Кроме того, необходимо поместить исходный код класса в папку, соответствующую пакету.

Если декларация имени пакета отсутствует, считается, что класс принадлежит пакету с именем default.

Вложенным пакетам соответствуют составные имена. Например, если мы имеем пакет с именем pkg1, в который вложен пакет с именем pkg2, в который вложен пакет с именем pkg3, то объявление, что класс с именем MyClass1 находится в пакете pkg3, будет выглядеть как

package pkg1.pkg2.pkg3;

class MyClass1 {

….

}

Внутри фигурных скобок должно содержатся описание класса. Оно заменено многоточием.

В качестве разделителя имён пакетов в программе используется точка независимо от типа операционной системы. Хотя в разных операционных системах вложенность папок будет обозначаться по-разному:

в MS Windows ® : pkg1\pkg2\pkg3\

в Unix и Linux : pkg1/pkg2/pkg3/

в Mac OS : pkg1:pkg2:pkg3:

При создании проекта в среде NetBeans помещение класса в пакет происходит автоматически.

При декларации класса можно указывать, что он общедоступен, с помощью модификатора доступа public:

public class MyClass2 {

….

}

В этом случае возможен доступ к данному классу из других пакетов.

Если же модификатор public отсутствует, как в случае MyClass1, то доступ к классу разрешён только из классов, находящихся с ним в одном пакете. Про такие файлы говорят, что у них пакетный вариант доступа (в C++ аналогичный вид доступа называется “дружественным” - friend).

В файле .java можно располагать только один общедоступный класс и произвольное число классов с пакетным уровнем видимости.

Класс может использовать общедоступные (public) классы из других пакетов напрямую, с указанием полного имени класса в пространстве имён, включающего имя пакета. Например, доступ к классу MyClass2 в таком варианте осуществляется как

pkg1.pkg2.pkg3.MyClass2

Для того, чтобы задать переменную объектного типа, надо до того указать её класс. В нашем случае это будет выглядеть так:

pkg1.pkg2.pkg3.MyClass2 myObject;

Для того чтобы отличать имена классов от имён пакетов, в Java принято имена пакетов писать только строчными буквами, имена классов начинать с заглавной буквы, а имена полей данных (в том числе имена объектных переменных) и методов начинать со строчной буквы. Если имя класса, поля данных или метода (но не пакета!) состоит из нескольких слов, каждое новое слово принято или писать с заглавной буквы. Новое слово также можно отделять от предыдущего символом подчёркивания. Таким образом, из названия javax.swing.JMenuItem понятно, что javax и swing – пакеты, а JMenuItem – имя класса.

Существует способ доступа к именам из другого пакета “напрямую”, без указания каждый раз полного пути в пространстве имён. Это делается с помощью оператора import. Если мы хотим импортировать имя класса MyClass2 из пакета pkg3, то после объявления имени нашего пакета (например, mypack1), но до объявления нашего класса (например, MyClass3) пишется

import pkg1.pkg2.pkg3.MyClass2;

При этом в классе MyClass3 имя MyClass2 можно использовать напрямую, без указания перед ним имени пакета pkg1.pkg2.pkg3. При этом задание переменной будет выглядеть так:

MyClass2 myObject;

Но если мы импортируем пакеты, содержащие классы с одинаковыми именами, требуется указание полного имени класса – квалифицированного именем пакета.

Если мы хотим импортировать имена всех классов из пакета, в операторе import после имени пакета вместо имени класса следует написать * . Пример:

import pkg1.pkg2.pkg3.*;

Заметим, что импортируются только имена файлов, находящихся точно на уровне указанного пакета. Импорта имён из вложенных в него пакетов не происходит. Например, если записать import pkg1.*; или import pkg1.pkg2.*; , то имя класса MyClass2 не будет импортировано, так как хотя он и находится внутри pkg1 и pkg2, но не непосредственно, а в пакете pkg3.

Имеется одно исключение из правила для импорта: классы ядра языка Java, содержащиеся в пакете java.lang, импортируются автоматически без указания имени пакета.

Пример: объявление графического объекта g, имеющего тип , может проводиться тремя способами.

Во-первых, напрямую, с указанием имени пакета и класса:

java.awt.Graphics g;

Во-вторых, с предварительным импортом класса Graphics из пакета java.awt и последующим указанием имени этого класса без его спецификации именем пакета:

import java.awt.Graphics;

Graphics g;

В-третьих, с предварительным импортом всех классов (в том числе Graphics) из пакета java.awt и последующим указанием имени этого класса без его спецификации именем пакета:

import java.awt.*;

Graphics g;

2.4. Базовые пакеты и классы Java

В пакете java находятся следующие пакеты и классы:

Пакет, класс

Краткое описание

java.applet

Поддержка работы с апплетами.

java.awt

Базовый пакет работы с графическим пользовательским интерфейсом (Abstract Window Toolkit - Абстрактный Инструментарий графического Окна).

java.beens

Поддержка компонентной модели JavaBeans.

java.io

Поддержка базовых средств ввода-вывода.

java.lang

Содержит базовые классы языка Java. Автоматически импортируется в любую программу без указания имени пакета.

java.lang.reflect

Поддерживает механизм доступа к классам как метаобъектам, обеспечивающий возможность динамического выяснения программой, какие возможности поддерживает класс. Данный механизм называется reflection - “отражение”.

java.lang.Math

Класс, обеспечивающий поддержку основных математических функций, а также простейшее средство генерации псевдослучайных чисел.

java.math

Поддержка вычислений с целыми числами произвольной длины, а также числами в формате с плавающей точкой произвольной точности.

java.net

Поддержка работы в Интернет, а также соединений через сокеты (sockets).

java.nio

Содержит классы и пакеты для поддержки сетевых соединений, расширяющие возможности пакета java.io . В частности, содержит классы контейнеров (буферов) для создания списков с данными различных примитивных типов, а также пакеты channels (“каналы соединения, коннекции”) и charset (“национальный набор символов”). Пакет charset обеспечивает поддержку перекодирования из символов Unicode в последовательность байт для передачи через канал связи, а также обратное преобразование.

java.rmi

Поддержка вызовов удалённых методов.

java.security

Поддержка специальных средств, обеспечивающих безопасность приложения, в том числе при работе в компьютерных сетях (списки доступа, сертификаты безопасности, шифрование и т.д.).

java.sql

Поддержка SQL-запросов к базам данных.

java.text

Поддержка специальных средств, обеспечивающих локализацию программ – классы, обеспечивающие настройки для работы с текстом, датами, текстовым представлением чисел. Кроме того, содержит средства для зависимого от локализации сравнения строк.

java.util

Содержит важнейшие классы для работы со структурами данных (в том числе – необходимых для работы с событиями и датами). В частности – поддержку работы с массивами (сортировка, поиск), а также расширенные средства генерации псевдослучайных чисел.

java.util.jar

Поддержка работы с jar-архивами (базовым видом архивов в Java).

java.util.zip

Поддержка работы с zip-архивами.

Пакет javax обеспечивает поддержку новых возможностей, введённых в Java 2. В нём находятся следующие пакеты:

Пакет, класс

Краткое описание

javax.accessibility

Обеспечивает настройку специальных возможностей представления информации для людей с плохим зрением, слухом и т.п., а также других случаев, когда требуется специализированный доступ для управления информационными объектами.

javax.activity

Вспомогательный пакет для работы с компонентами.

javax.crypto

Поддержка шифрования-расшифровки данных.

javax.imageio

Поддержка работы с изображениями (ввод-вывод).

javax.management

Поддержка работы с управляющими компонентами (MBean – Management Bean).

javax.naming

Поддержка работы с пространством имён компонентов.

javax.net

Поддержка работы в Интернет, а также соединений через сокеты (sockets). – Расширение возможностей java.net

javax.print

Поддержка работы с печатью документов.

javax.rmi

Поддержка вызовов удалённых методов. – Расширение возможностей java.rmi

javax.security

Поддержка специальных средств, обеспечивающих безопасность приложения. – Расширение возможностей java.security

javax.sound

Поддержка работы со звуковыми потоками и файлами.

javax.sql

Поддержка SQL-запросов к базам данных. – Расширение возможностей java.sql

javax.swing

Библиотека основных графических компонентов в Java 2.

javax.transaction

Поддержка работы с транзакциями.

javax.xml

Поддержка работы с XML документами и парсерами.

Пакет com.sun от фирмы Sun Microsystems в основном обеспечивает расширение возможностей пакета javax. В нём находятся следующие пакеты:

Пакет, класс

Краткое описание

com.sun.accessibility

Дополнение к пакету javax.accessibility

com.sun.beans

Дополнение к пакету java.beens

com.sun.corba

Поддержка работы в компьютерных сетях с базами данных по технологии CORBA (Common Object Request Broker Architecture).

com.sun.crypto

Дополнение к пакету javax.crypto

com.sun.image

Поддержка работы с изображениями

com.sun.imageio

Дополнение к пакету javax.imageio

com.sun.java

Поддержка стилей показа приложений (см.раздел “Внешний вид приложения”), а также служебные утилиты для работы с браузерами и WWW-документами.

com.sun.java_cup

Поддержка технологии JavaCup

com.sun.jlex

Поддержка работы лексического анализатора.

com.sun.jmx

Дополнение к пакету javax.management

com.sun.jndi

Пакет в процессе разработки.

com.sun.management

Дополнение к пакету javax.management

com.sun.media

Поддержка работы со звуком.

com.sun.naming

Дополнение к пакету javax.naming

com.sun.net

Дополнение к пакету javax.net

com.sun.org

Поддержка взаимодействия с сервером Apache, средства работы с базами данных по технологии CORBA.

com.sun.rmi

Дополнение к пакету javax.rmi

В пакете org находятся следующие пакеты, предоставляемые свободным сообществом разработчиков:

Пакет, класс

Краткое описание

org.ietf

Поддержка защищенных соединений по протоколу GSS (Kerberos v5 ).

org.jdesktop

Менеджер размещения GroupLayout.

org.omg

Средства для использования из программ на Java технологии CORBA, применяемой для создания распределенных объектных приложений.

org.w3c

Интерфейсы для работы с XML-документами в соответствии со спецификацией DOM.

org.xml

Поддержка работы с XML-документами.

2.5. Создание в NetBeans простейшего приложения Java

Создадим с помощью среды NetBeans приложение Java. Для этого запустим интегрированную среду разработки (IDE) NetBeans , и выберем в главном меню File/New Project… В открывшемся диалоге выберем General / Java Application / Next>

Создание нового проекта. Шаг 1.

После чего можно нажимать кнопку Finish – значения по умолчанию для начала менять не стоит. Это можно будет делать потом, когда вы освоитесь со средой разработки.

Создание нового проекта. Шаг 2.

На следующем рисунке показано, как выглядит редактирование исходного кода приложения в среде NetBeans.

В левом верхнем окне “Projects” показывается дерево проектов. В нашем случае это дерево для проекта JavaApplication1. Это окно может быть использовано для одновременного показа произвольного числа проектов. По умолчанию все деревья свёрнуты, и нужные узлы следует разворачивать щелчком по узлу с “плюсиком” или двойным щелчком по соответствующему имени.

В правом окне “Source” показывается исходный код проекта.

В левом нижнем окне “Navigator” показывается список имён членов класса приложения – имена переменных и подпрограмм. Двойной щелчок по имени приводит к тому, что в окне редактора исходного кода происходит переход на то место, где задана соответствующая переменная или подпрограмма.

Редактирование исходного кода приложения

Рассмотрим, как выглядит сгенерированный исходный код нашего приложения Java:

/*

* Main.java

*

* Created on 21 Июнь 2006 г., 13:08

*

* To change this template, choose Tools | Template Manager

* and open the template in the editor.

*/

package javaapplication1;

/**

*

* @author User

*/

public class Main {

/** Creates a new instance of Main */

public Main() {

}

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

// TODO code application logic here

}

}

Сначала идёт многострочный комментарий /* … */ Он содержит информацию об имени класса и времени его создания.

Затем объявляется, что наш класс будет находиться в пакете javaapplication1.

После этого идёт многострочный комментарий /** … */ , предназначенный для автоматического создания документации по классу. В нём присутствует инструкция задания метаданных с помощью выражения @author – информация об авторе проекта для утилиты создания документации javadoc. Метаданные – это некая информация, которая не относится к работе программы и не включается в неё при компиляции, но сопровождает программу и может быть использована другими программами для проверки прав на доступ к ней или её распространения, проверки совместимости с другими программами, указания параметров для запуска класса и т.п. В данном месте исходного кода имя “User” берётся средой разработки из операционной системы по имени папки пользователя. Его следует заменить на имя реального автора, т.е. в нашем случае на “Вадим Монахов”.

Далее следует объявление класса Main, который является главным классом приложения. В нём объявлены две общедоступных (public) подпрограммы. Первой из них является конструктор:

public Main() {

}

Его имя совпадает с именем класса. Он занимается созданием объектов типа Main. Обычно такой конструктор вызывается из метода main, и с его помощью создаётся всего один объект, “олицетворяющий” собой приложение. Но, вообще говоря, таких объектов в простых программах может и не создаваться, как это и происходит в нашем случае.

Все классы и объекты приложения вызываются и управляются из метода main, который объявлен далее и выглядит следующим образом:

public static void main(String[] args) {

}

Он является методом класса, и поэтому для его работы нет необходимости в создании объекта, являющегося экземпляром класса Main. Хотя если этот объект создаётся, это происходит во время работы метода main.

Метод main является главным методом приложения и управляет работой запускаемой программы. Он автоматически вызывается при запуска приложения. Параметром args этого метода является массив строк, имеющий тип String[].Это параметры командной строки, которые передаются в приложение при его запуске. Слово String означает “Строка”, а квадратные скобки используются для обозначения того, что это массив строк.

После окончания выполнения метода main приложение завершает свою работу.

При объявлении любого метода в Java сначала указывается модификатор видимости, указывающий права доступа к методу, затем другие модификаторы, после чего следует тип возвращаемого методом значения. Если модификатор видимости не указан, считается, что это private (читается “прайвит”)– “закрытый, частный”, не позволяющий доступ к методу из других классов.

Конструкторы представляют особый случай, в них имя типа и имя метода совпадают. В Java они не считаются методами, хотя в других языках программирования такого тонкого различия не делается.

Далее следует имя метода, после чего в круглых скобках идёт список параметров (аргументов), передаваемых в данный метод при его вызове. После этого в фигурных скобках идёт тело метода , то есть его реализация – пишется тот алгоритм, который будет выполняться при вызове метода.

В языке Java, как и в C/C++ подпрограммы всегда являются подпрограммами-функциями, возвращающими какое-либо значение. Если надо написать подпрограмму-процедуру, в которой не надо возвращать никакого значения, в C/C++/Java пользуются подпрограммами-функциями с типом возвращаемого значения void – “пустота, пустое пространство”. Как и происходит в случае метода main.

Среда NetBeans создаёт заготовку методов – в них имеется пустое тело. Для осуществления методом какой-либо деятельности следует дописать свой собственный код. Напишем традиционный пример – вывод сообщения “Привет!”. Для этого вместо комментария

// TODO code application logic here

(“описать тут логику работы приложения”) напишем строку вывода текста

System.out.println("Привет!");

Класс System, “система”, имеет поле out, “наружу”. Это объект, предназначенный для поддержки вывода. У него есть метод println, предназначенный для вывода текста в режиме консоли.

Консольный ввод-вывод ранее широко применялся в операционных системах, ориентированных на работу в режиме командной строки. При этом основным средством взаимодействия пользователей с программами служила текстовая консоль ( “пульт управления”). В ней устройством ввода служила клавиатура, а устройством вывода – окно операционной системы, обеспечивающее вывод текста в режиме пишущей машинки (системным шрифтом с буквами, имеющими одинаковую ширину). Очень много примеров программ в учебных курсах по Java ориентированы на работу в таком режиме. В настоящее время в связи с тем, что подавляющее большинство пользователей работают с программами в графическом режиме, работу в консольном режиме нельзя рассматривать как основную форму ввода-вывода. Тем более, что NetBeans позволяет без особых усилий создавать графический пользовательский интерфейс (GUI – Graphics User Interface) приложения. А консольный режим следует применять только как промежуточный, удобный в отладочном режиме как средство вывода вспомогательной информации.

2.6. Компиляция файлов проекта и запуск приложения

В современных средах разработки используется два режима компиляции – compile (“скомпилировать”) и build (“построить”). В режиме “compile” происходит компиляция только тех файлов проекта, которые были изменены в процессе редактирования после последней компиляции. А в режиме “build” перекомпилируются заново все файлы.

Для компиляции проекта следует выбрать в меню среды разработки Build / Build Main Project (или, что то же, клавиша <F 11 >, или на панели инструментов иконка с голубой книжкой и гаечным ключом). При этом будут заново скомпилированы из исходных кодов все классы проекта.

Пункт Build / Clean and Build Main Project (или, что то же, комбинация клавиш <Shift > <F 11 >, или на панели инструментов иконка с оранжевой книжкой и веником) удаляет все выходные файлы проекта (очищает папки build и dist), после чего по новой компилируются все классы проекта.

Пункт Build / Generate Javadoc for JavaApplication 1” запускает создание документации по проекту. При этом из исходных кодов классов проекта выбирается информация, заключённая в документационные комментарии /** … */, и на её основе создаётся гипертекстовый HTML-документ.

Пункт Build / Complile Main . java (или, что то же, клавиша <F 9 >) компилирует выбранный файл проекта – в нашем случае файл Main.java, в котором хранятся исходные коды класса Main.

Для того чтобы запустить скомпилированное приложение из среды разработки, следует выбрать в меню среды разработки Run / Run Main Project (или, что то же, клавиша <F 6 >, или на панели инструментов иконка с зелёным и жёлтыми треугольниками). При запуске приложение всегда автоматически компилируется (но не “строится”), так что после внесения изменений для запуска обычно достаточно нажать <F 6 >.

После запуска нашего проекта в выходной консоли, которая находится в нижней части окна проекта, появится служебная информация о ходе компиляции и запуска:

Информация о ходе компиляции и запуска в выходной консоли.

В неё же осуществляется вывод методов System.out.print и System.out.println.

Метод System.out.print отличается от метода System.out.println только тем, что в println после вывода осуществляется автоматический переход на новую строку, а в print продолжается вывод в ту же строку консоли. Поэтому вывод

System.out.println("Привет!");

System.out.println("Привет!");

Даст текст

Привет!

Привет!

а

System.out.print("Привет!");

System.out.print("Привет!");

даст

Привет!Привет!

2.7. Структура проекта NetBeans

Рассмотрим, из каких частей состоит проект NetBeans. На рисунке показаны основные элементы, отображаемые в среде разработки.

Это Source Packages (пакеты исходного кода), Test Packages (пакеты тестирования), Libraries (библиотеки) и Test Libraries (библиотеки поддержки тестирования). Ветви дерева представления элементов проекта можно разворачивать или сворачивать путём нажатия на узлы, отмеченные плюсами и минусами. Мы пока будем пользоваться только пакетами исходного кода.

В компонентной модели NetBeans пакеты приложения объединяются в единую конструкцию – модуль. Модули NetBeans являются базовой конструкцией не только для создания приложений, но и для написания библиотек. Они представляют собой оболочку над пакетами (а также могут включать в себя другие модули).

В отличии от библиотек Java скомпилированный модуль – это не набор большого количества файлов, а всего один файл, архив JAR (Java Archive, архив Java). В нашем случае он имеет то же имя, что и приложение, и расширение .jar : это файл JavaApplication1.jar. Модули NetBeans гораздо лучше подходят для распространения, поскольку не только обеспечивают целостность комплекта взаимосвязанных файлов, но и хранят их в заархивированном виде в одном файле, что намного ускоряет копирование и уменьшает объём занимаемого места на носителях.

Отметим не очень удобную особенность NetBeans – после сохранения проекта и закрытия среды разработки не сохраняется конфигурация открытых окон и развёрнутых деревьев проекта - деревья проектов показываются в свёрнутом виде. Поэтому для того, чтобы вновь попасть в режим редактирования исходного кода нашего приложения, в окне Projects, “Проекты” (левом верхнем окне среды разработки) следует развернуть последовательность узлов JavaApplication1/Source Packages/javaapplication1/ . Это делается нажатием на плюсики в соответствующих узлах или двойным щелчком по имени узла. Затем надо сделать двойной щелчок с помощью левой кнопкой мыши по имени узла Main.java, либо с помощью щелчка правой кнопкой мыши по этому имени открыть всплывающее меню и выбрать в нём первый пункт – “Open”.

Имеется и более простой способ. По умолчанию сначала открывается окно Welcome (“Привет”, “Приветствие”). Но среда разработки сохраняет список открытых окон, и в верхней части окна редактирования кода щелчком мыши можно выбрать нужное имя окна. Хотя при этом не видна структура проекта, так что первый способ во многих случаях может быть предпочтительным.

Если вы открываете новый проект, старый не закрывается. И в дереве проектов видны все открытые проекты. То же относится и к списку открытых окон. Это позволяет работать сразу с несколькими проектами, например – копировать в текущий проект участки кода из других проектов. Один из открытых проектов является главным (Main Project) – именно он будет запускаться на исполнение по Run / Run Main Project . Для того, чтобы установить какой-либо из открытых проектов в качестве главного, следует в дереве проектов с помощью правой кнопкой мыши щелкнуть по имени проекта и выбрать пункт меню Set Main Project. Аналогично, для того, чтобы закрыть какой-либо из открытых проектов, следует в дереве проектов с помощью правой кнопкой мыши щелкнуть по имени проекта и выбрать пункт меню Close Project.

Рассмотрим теперь структуру папок проекта NetBeans. По умолчанию головная папка проекта располагается в папке пользователя. В операционной системе.

Windows® XP проект по умолчанию располагается в папке C:\Documents and Settings\ИмяПользователя\ . Дальнейшее расположение папок и файлов приведено ниже, при этом имена папок выделены жирным шрифтом, а имена вложенных папок и файлов записаны под именами их головных папок и сдвинуты относительно них вправо.

build

classes

javaapplication1

Main.class

… .class

META-INF

dist

javadoc

lib

JavaApplication1jar

README.TXT

nbproject

src

javaapplication1

Main.java

… .java

… .form

META-INF

test

build.xml

manifest.mf

- В папке build хранятся скомпилированные файлы классов, имеющие расширение .class.

- В папке dist - файлы, предназначенные для распространения как результат компиляции (модуль JAR приложения или библиотеки, а также документация к нему).

- В папке nbproject находится служебная информация по проекту.

- В папке src - исходные коды классов. Кроме того, там же хранится информация об экранных формах (которые будут видны на экране в виде окон с кнопками, текстом и т.п.). Она содержится в XML-файлах, имеющих расширение .form.

- В папке test - сопроводительные тесты, предназначенные для проверки правильности работы классов проекта.

Приведём перевод файла README.TXT, находящегося в папке dist - там же, где архив JAR, предназначенный для распространения как файл приложения:

========================

ОПИСАНИЕ ВЫВОДА КОМПИЛЯЦИИ

========================

Когда Вы компилируете проект приложения Java, которое имеет главный класс, среда разработки (IDE) автоматически копирует все файлы JAR-архивов, указанные в classpath ваших проектов,

в папку dist/lib. Среда разработки также автоматически прибавляет путь к каждому из этих архивов в файл манифеста приложения (MANIFEST.MF).

Чтобы запустить проект в режиме командной строки, зайдите в папку dist и

наберите в режиме командной строки следующий текст:

java -jar "JavaApplication3.jar"

Чтобы распространять этот проект, заархивируйте папку dist (включая папку lib), и распространяйте ZIP-архив.

Замечания:

* Если два JAR-архива, указанные в classpath ваших проектов, имеют одинаковое имя, в папку lib будет скопирован только первый из них.

* Если в classpath указана папка с классами или ресурсами, ни один из

элементов classpath не будет скопирован в папку dist.

* Если в библиотеке, указанной в classpath, также имеется элемент classpath, указанные в нём элементы должны быть указаны в пути classpath времени выполнения проектов.

* Для того чтобы установить главный класс в стандартном проекте Java, щёлкните правой кнопкой мыши в окне Projects и выберите Properties. Затем выберите Run и введите данные

о названии класса в поле Main Class. Кроме того, Вы можете вручную ввести

название класса в элементе Main-Class манифеста.

2.8. Создание в NetBeans приложения Java с графическим интерфейсом

Экранной формой называется область, которая видна на экране в виде окна с различными элементами - кнопками, текстом, выпадающими списками и т.п. А сами эти элементы называются компонентами.

Среды, позволяющие в процессе разработки приложения в интерактивном режиме размещать на формы компоненты и задавать их параметры, называются RAD-средами. RAD расшифровывается как Rapid Application Development - быстрая разработка приложений.

В NetBeans и других современных средах разработки такой процесс основан на объектной модели компонентов, поэтому он называется Объектно-Ориентированным Дизайном (OOD – Object-Oriented Design).

NetBeans является RAD-средой и позволяет быстро и удобно создавать приложения с развитым графическим пользовательским интерфейсом (GUI). Хотя языковые конструкции Java, позволяющие это делать, не очень просты, на начальном этапе работы с экранными формами и их элементами нет необходимости вникать в эти тонкости. Достаточно знать основные принципы работы с такими проектами.

С точки зрения автора изучение того, как создавать приложения с графическим интерфейсом, весьма важно для начинающих программистов, и это следует делать с самых первых шагов по изучению Java.

Во-первых, с самого начала осваивается создание полноценных приложений, которые можно использовать в полезных целях. Трудно месяцами изучать абстрактные концепции, и только став профессионалом иметь возможность сделать что-то такое, что можно показать окружающим. Гораздо интереснее и полезнее сразу начать применять полученные знания на практике.

Во-вторых, такой интерфейс при решении какой-либо задачи позволяет лучше сформулировать, какие параметры надо вводить, какие действия и в какой последовательности выполнять, и что в конце концов получается. И отобразить всё это на экране: вводимым параметрам будут соответствовать пункты ввода текста, действиям – кнопки и пункты меню, результатам – пункты вывода текста.

Пример открытия проекта с существующим исходным кодом.

В NetBeans 5.0 имелся хороший пример GUI-приложения, однако в NetBeans 5.5 он отсутствует. Поэтому для дальнейшей работы следует скопировать аналогичный пример с сайта автора или сайта, на котором выложен данный учебный курс. Пример называется JavaApplicationGUI_example.

Сначала следует распаковать zip-архив, и извлечь находящуюся в нём папку с файлами проекта в папку с вашими проектами (например, C:\Documents and Settings\User). Затем запустить среду NetBeans, если она не была запущена, и закрыть имеющиеся открытые проекты, чтобы они не мешали. После чего выбрать в меню File/Open Project, либо или на панели инструментов иконку с открывающейся фиолетовой папочкой, либо нажать комбинацию клавиш <Shift>+<Ctrl>+O. В открывшемся диалоге выбрать папку JavaApplicationGUI_example (лучше в неё не заходить, а просто установить выделение на эту папку), после чего нажать кнопку Open Project Folder.

При этом, если не снимать галочку “Open as Main Project”, проект автоматически становится главным.

В окне редактора исходного кода появится следующий текст:

/*

* GUI_application.java

*

* Created on 22 Июня 2006 г., 13:41

*/

package java_gui_example;

/**

*

* @author Вадим Монахов

*/

public class GUI_application extends javax.swing.JFrame {

/**

* Creates new form GUI_application

*/

public GUI_application() {

initComponents();

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

*/

+Generated Code

private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt)

{

System.exit(0);

}

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

new GUI_application().setVisible(true);

}

});

}

// Variables declaration - do not modify

private javax.swing.JMenuItem aboutMenuItem;

private javax.swing.JMenuItem contentsMenuItem;

private javax.swing.JMenuItem copyMenuItem;

private javax.swing.JMenuItem cutMenuItem;

private javax.swing.JMenuItem deleteMenuItem;

private javax.swing.JMenu editMenu;

private javax.swing.JMenuItem exitMenuItem;

private javax.swing.JMenu fileMenu;

private javax.swing.JMenu helpMenu;

private javax.swing.JMenuBar menuBar;

private javax.swing.JMenuItem openMenuItem;

private javax.swing.JMenuItem pasteMenuItem;

private javax.swing.JMenuItem saveAsMenuItem;

private javax.swing.JMenuItem saveMenuItem;

// End of variables declaration

}

Поясним некоторые его части. Указание пакета java_gui_example, в котором будет располагаться код класса приложения, нам уже знакомо. Декларация самого класса GUI_application в данном случае несколько сложнее, чем раньше:

public class GUI_application extends javax.swing.JFrame

Она означает, что задаётся общедоступный класс GUI_application, который является наследником класса JFrame, заданного в пакете swing, вложенном в пакет javax. Слово extends переводится как “расширяет” (класс-наследник всегда расширяет возможности класса-прародителя).

Общедоступный конструктор GUI_application()создаёт объект приложения и инициализирует все его компоненты, методом initComponents(), автоматически генерируемом средой разработки и скрываемом в исходном коде узлом +Generated Code.

Развернув узел, можно увидеть реализацию этого метода, но изменить код нельзя. Мы не будем останавливаться на том, что в нём делается.

Далее следует закрытый (private) метод

private void exitMenuItemActionPerformed

Он будет обсуждаться чуть позже. Метод

public static void main(String[] args)

нам уже знаком – это главный метод приложения. Он является методом класса нашего приложения и автоматически выполняется Java-машиной при запуске приложения. В данном примере метод создаёт экранную форму приложения и делает её видимой. Для того, чтобы понять, как это делается, потребуется изучить довольно много материала в рамках данного курса.

Далее следует область объявления компонентов– пунктов меню нашей формы. Она автоматически создаётся в исходном коде редактором экранных форм и недоступна для изменения в редакторе исходного кода.

Запущенное приложение. Приложение с раскрытым меню.

При запуске приложения экранная форма выглядит так, как показано на рисунке. В ней уже имеется заготовка меню, которое способно разворачиваться и сворачиваться, и даже работает пункт Exit – “Выход”. При нажатии на него происходит выход из приложения.

Именно за нажатие на этот пункт меню несёт ответственность оператор exitMenuItemActionPerformed. При проектировании экранной формы он назначен в качестве обработчика события – подпрограммы, которая выполняется при наступлении события. В нашем случае событием является выбор пункта меню Exit, и при этом вызывается обработчик exitMenuItemActionPerformed. Внутри него имеется всего одна строчка

System.exit(0);

Она вызывает прекращение выполнения метода main и выход из приложения с нулевым кодом завершения. Как правило, ненулевой код завершения возвращают при аварийном завершении приложения для того, чтобы по его значению можно было выяснить причины “вылета” программы.

2.9. Редактор экранных форм

Нажмём закладку Design (“дизайн”) в левой верхней части редактора исходного кода. При этом мы переключимся из режима редактирования исходного кода (активна закладка Source – “исходный код”) в режим редактирования экранной формы, как это показано на рисунке.

Редактирование экранной формы.

Вместо исходного кода показывается внешний вид экранной формы и находящиеся на ней компоненты. Справа от окна, в котором показывается экранная форма в режиме редактирования, расположены окна Palette (“палитра”) палитры компонентов и окно Properties (“свойства”) показа и редактирования свойств текущего компонента.

Свойство – это поле данных, которое после изменения значения может проделать какое-либо действие. Например, при изменении значения ширины компонента отрисовать на экране компонент с новой шириной. “Обычное” поле данных на такое не способно. Таким образом, свойство – это “умное поле данных”.

Палитра компонентов предназначена для выбора типа компонента, который нужен программисту для размещения на экранной форме. Например, добавим на нашу форму компонент типа JButton (сокращение от Java Button – “кнопка Java”). Для этого щёлкнем мышью по пункту JButton на палитре и передвинем мышь в нужное место экранной формы. При попадании мыши в область экранной формы на ней появляется кнопка стандартного размера, которая передвигается вместе с мышью. Щелчок в нужном месте формы приводит к тому, что кнопка остаётся в этом месте. Вокруг неё показываются рамка и маленькие квадратики, обозначающие, что наш компонент является выделенным. Для него осуществляется показ и редактирование свойств в окне Properties.

Кроме того, от выделенного компонента исходят линии, к которым идет привязка для задания положения компонента на форме.

По умолчанию надписи на компонентах задаются как имя типа, после которого идёт номер компонента. Но вместо заглавной буквы, в отличие от имени типа, используется строчная. Поэтому первая кнопка будет иметь надпись jButton1, вторая – jButton2, и так далее. Такие же имена будут приобретать автоматически создаваемые в исходном коде переменные, соответствующие кнопкам.

Изменить надпись на кнопке можно несколькими способами. Во-первых, сделав по ней двойной щелчок, и отредактировав текст. Во-вторых, перейдя в окно Properties, изменив значение свойства Text и нажав <Enter> для завершения ввода. В-третьих, изменив аналогичным образом свойство label. Наконец, можно в окне Properties отредактировать текст не в однострочном поле ввода значений для свойств Text или label, а открыв многострочный редактор путём нажатия на кнопку, находящуюся справа от пункта редактирования значения свойства. Однако многострочность редактора не помогает сделать надпись на кнопке многострочной.

Введём на кнопке надпись “OK” – используем эту кнопку для выхода из программы.

Редактирование свойств компонента

Размер компонента задаётся мышью путём хватания за рамку и расширения или сужения по соответствующим направлениям. Установка на новое место – перетаскиванием компонента мышью.

Некоторые свойства выделенного компонента (его размер, положение, текст) можно изменять непосредственно в области экранной формы. Однако большинство свойств просматривают и меняют в окне редактирования свойств. Оно состоит из двух столбцов: в левом показываются имена свойств, в правом – их значения. Значения, стоящие в правом столбце, во многих случаях могут быть отредактированы непосредственно в ячейках таблицы. При этом ввод оканчивается нажатием на <Enter> или выходом из редактируемой ячейки, а отменить результаты неоконченного ввода можно нажатием <Escape>.

В правой части каждой ячейки имеется кнопка с надписью “…” – в современных операционных системах принято добавлять три точки в названии пунктов меню и кнопок, после нажатия на которые открывается диалоговое окно. В данном случае раскрывается окно специализированного редактора соответствующего свойства, если он существует.

Если требуется просматривать и редактировать большое количество свойств компонента, бывает удобнее щёлкнуть правой кнопкой мыши по нужному компоненту и в появившемся всплывающем меню выбрать пункт “Properties”. В этом случае откроется отдельное окно редактирования свойств компонента. Можно держать открытыми одновременно произвольное количество таких окон.

Булевские свойства в колонке значений свойств показываются в виде кнопок выбора checkbox – квадратиков с возможностью установки галочки внутри. Если галочки нет, значение свойства false, если есть – true.

Перечислим на примере кнопки ряд некоторых важнейших свойств, которые можно устанавливать для компонентов. Многие из них относятся и к другим компонентам.

Название свойства

Что оно задаёт

background

Цвет фона

componentPopupMenu

Позволяет назначать всплывающее меню, появляющееся по нажатию правой кнопкой мыши в области компонента.

font

Фонт, которым делается надпись на компоненте.

foreground

Цвет фонта, которым делается надпись на компоненте.

icon

Картинка, которая рисуется на компоненте рядом с текстом.

text

Текст (надпись) на компоненте.

toolTipText

Всплывающая подсказка, появляющаяся через некоторое время при наведении курсора мыши на компонент.

border

Тип рамки вокруг компонента.

borderPainted

Рисуется ли рамка вокруг компонента.

contentAreaFilled

Имеется ли заполнение цветом внутренней области компонента (для кнопок оно создаёт эффект трёхмерности, без заполнения кнопка выглядит плоской).

defaultCapable

Способна ли кнопка быть “кнопкой по умолчанию”: при нажатии <Enter> автоматически происходит нажатие “кнопки по умолчанию” (такая кнопка на экранной форме должна быть одна).

enabled

Доступен ли компонент. По умолчанию все создаваемые на форме компоненты доступны. Недоступные компоненты рисуются более блеклыми красками.

В качестве примера добавим всплывающую подсказку для нашей кнопки: введём текст “Эта кнопка предназначена для выхода из программы” в поле, соответствующее свойству toolTipText. К сожалению, подсказка может быть только однострочной – символы перевода на новую строку при выводе подсказки игнорируются, даже если они заданы в строке программным путём.

Наконец, зададим действие, которое будет выполняться при нажатии на кнопку – обработчик события (event handler) нажатия на кнопку. Для этого сначала выделим кнопку, после чего щёлкнем по ней правой кнопкой мыши, и в появившемся всплывающем меню выберем пункт Events/Action/actionPerformed.

Назначение обработчика события

Events означает “События”, Action – “Действие”, actionPerformed – “выполненное действие”.

После этого произойдёт автоматический переход в редактор исходного кода, и там появится заготовка обработчика события:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

// TODO add your handling code here:

}

Аналогичный результат можно получить и более быстрым способом – после того, как мы выделим кнопку в окне редактирования формы (Design), в окне Navigator показывается и выделяется имя этой кнопки. Двойной щелчок по этому имени в окне навигатора приводит к созданию заготовки обработчика события.

Рядом с обработчиком jButton1ActionPerformed будет расположен уже имеющийся обработчик события, срабатывающий при нажатии на пункт меню “Выход”:

private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {

System.exit(0);

}

Заменим в нашем обработчике события строку с комментарием на код, вызывающий выход из программы:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

System.exit(0);

}

Теперь после запуска нашего приложения подведение курсора мыши к кнопке приведёт к появлению всплывающей подсказки, а нажатие на кнопку – к выходу из программы.

Часто встречающийся случай – показ сообщения при наступлении какого-либо события, например – нажатия на кнопку. Этом случае вызывают панель с сообщением:

javax.swing.JOptionPane.showMessageDialog(null,"Меня нажали");

Если классы пакета javax.swing импортированы, префикс javax.swing при вызове не нужен.

2.10. Внешний вид приложения

На этапе редактирования приложения внешний вид его компонентов соответствует платформе. Однако после запуска он становится совсем другим, поскольку по умолчанию все приложения Java показываются в платформо-независимом виде.:

Внешний вид запущенного приложения с платформо-независимым пользовательским интерфейсом, задаваемым по умолчанию

Кроме того, наше приложение появляется в левом верхнем углу экрана, а хотелось бы, чтобы оно появлялось в центре.

Для того, чтобы показать приложение в платформо-ориентированном виде (то есть в том виде, который использует компоненты и настройки операционной системы), требуется изменить код конструктора приложения, вставив перед вызовом метода initComponents задание типа пользовательского интерфейса (User’s Interface, сокращённо UI):

import javax.swing.*;

import java.awt.*;

...

public GUI_application() {

try{

UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );

}catch(Exception e){};

initComponents();

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Dimension frameSize = getSize();

setLocation(new Point( (screenSize.width-frameSize.width)/2,

(screenSize.height-frameSize.width)/2 )

);

}

Внешний вид запущенного приложения с платформо-ориентированным пользовательским интерфейсом в операционной системе Windows ® XP

Код, следующий после вызова initComponents(), предназначен для установки окна приложения в центр экрана.

Имеется возможность задания ещё одного платформо-независимого вида приложения – в стиле Motiff, используемого в операционной системе Solaris® . Для установки такого вида вместо вызова

UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()

Следует написать

UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

Внешний вид запущенного приложения с платформо-независимым пользовательским интерфейсом в стиле Motiff

Использованные конструкции станут понятны читателю после изучения дальнейших разделов методического пособия.

2.11. Ведение проектов

Для того, чтобы не запутаться в разных проектах и их версиях, особенно с учётом того, что учебные проекты бывает необходимо часто переносить с одного компьютера на другой, следует серьёзно отнестись к ведению проектов. Автором в результате многолетней практики работы с разными языками и средами программирования выработана следующая система (откорректированная в применении к среде NetBeans):

· Под каждый проект создаётся папка с названием проекта. Будем называть её папкой архива для данного проекта. Названия используемых папок могут быть русскоязычными, как и имена приложений и файлов.

· При создании нового проекта среда разработки предлагает ввести имя папки, где его хранить - следует указать имя папки архива. Кроме того, предлагается ввести имя проекта. Это имя будет использовано средой NetBeans для создания папки проекта, так и для названия вашего приложения. Для того, чтобы облегчить работу с вашим приложением в разных странах, рекомендуется делать это название англоязычным. В папке проекта среда разработки автоматически создаст систему вложенных папок проекта и все его файлы. Структура папок проектов NetBeans была описана ранее.

· Если берётся проект с существующим исходным кодом, его папка копируется в папку нашего архива либо вручную, либо выбором соответствующей последовательности действий в мастере создания проектов NetBeans.

· При получении сколько-нибудь работоспособной версии проекта следует делать его архивную копию. Для этого в открытом проекте в окне “Projects” достаточно щелкнуть правой кнопкой мыши по имени проекта, и в появившемся всплывающем меню выбрать пункт “Copy Project”. Откроется диалоговая форма, в которой предлагается автоматически образованное имя копии – к первоначальному имени проекта добавляется подчёркивание и номер копии. Для первой копии это _1, для второй _2, и так далее. Причём головная папка архива по умолчанию остаётся той же, что и у первоначального проекта. Что очень удобно, поскольку даёт возможность создавать копию всего тремя щелчками мышки без набора чего-либо с клавиатуры.

Создание рабочей копии проекта

Скопированный проект автоматически возникает в окне “Projects”, но не становится главным. То есть вы продолжаете работать с прежним проектом, и все его открытые окна сохраняются. Можно сразу закрыть новый проект – правой кнопкой мыши щёлкнуть по его имени, и в появившемся всплывающем меню выбрать пункт “Close Project”.

Для чего нужна такая система ведения проектов? Дело в том, что у начинающих программистов имеется обыкновение разрушать результаты собственного труда. Они развивают проект, не сохраняя архивов. Доводят его до почти работающего состояния, после чего ещё немного усовершенствуют, затем ещё – и всё перестаёт работать. А так как они вконец запутываются, восстановить работающую версию уже нет возможности. И им нечего предъявить преподавателю или начальнику!

Поэтому следует приучиться копировать в архив все промежуточные версии проекта, более работоспособные, чем уже сохранённые в архив. В реальных проектах трудно запомнить все изменения, сделанные в конкретной версии, и, что важнее, все взаимосвязи, вызвавшие эти изменения. Поэтому даже опытным программистам время от времени приходится констатировать: “Ничего не получается!” И восстанавливать версию, в которой ещё не было тех нововведений, которые привели к путанице. Кроме того, часто бывает, что новая версия в каких-то ситуациях работает неправильно. И приходится возвращаться на десятки версий назад в поисках той, где не было таких “глюков”. А затем внимательно сравнивать работу двух версий, выясняя причину неправильной работы более поздней версии. Или убеждаться, что все предыдущие версии также работали неправильно, просто ошибку не замечали.

2.11. Редактирование меню экранной формы

Имеются случаи, когда процесс редактирования компонентов несколько отличается от описанного выше. Например, для главного меню экранной формы и для всплывающих меню.

Рассмотрим, как изменить текст пунктов меню формы с английского на русский. Если щёлкнуть мышью по какому-либо пункту (item) меню, в окне редактора свойств появятся значения свойств этого пункта. И мы легко сменим “File” на “Файл”, “Edit” на “Правка”, “Help” на “Справка”. Для того, чтобы без компиляции и запуска программы посмотреть, как будет выглядеть наша экранная форма, можно нажать иконку Preview Design (третья по счёту после закладки Design в окне редактирования экранной формы).

Но вложенные пункты меню, появляющиеся при выборе любого из пунктов верхнего уровня, так отредактировать невозможно. Они редактируются немного другим путём. При переходе в режим дизайна, а также в этом режиме при щелчке в области экранной формы, в левом нижнем окне (Inspector - “инспектор компонентов”) среды разработки появляется список компонентов экранной формы. Навигатор позволяет просматривать деревья вложенности различных элементов проекта.

Сама экранная форма является экземпляром класса JFrame (от Java Frame – “окно, кадр”, предоставляемое языком Java). В окне инспектора после схематического изображения компонента и имени соответствующей ему переменной в квадратных скобках указывается тип компонента. Развернём узел для нашей формы типа JFrame, а также вложенные узлы menuBar типа JMenuBar и fileMemu типа JMenu.

Окно инспектора компонентов Развёрнутое дерево вложенности

Мы увидим имена переменных, соответствующих всем пунктам меню, вложенным в файловое меню: openMenuItem, saveMenuItem, saveAsMenuItem, exitMenuItem. Щелчок по имени openMenuItem в окне инспектора компонентов приведёт к тому, что в окне редактирования свойств появятся значения свойств данного пункта меню. В поле Text заменим слово “Open” на “Открыть”. Затем перейдём на пункт saveMenuItem, и так далее. В результате получим экранную форму с пунктами меню на русском языке.

Рассмотрим теперь создание всплывающего меню, появляющегося при щелчке по какому-либо компоненту нашей формы. Качестве примера назначим всплывающее меню кнопке выхода. Для других компонентов процесс будет абсолютно аналогичным.

Новый узел jPopupMenu 1 Содержание узла

В режиме дизайна (закладка Design) выберем мышью в палитре компонентов (окно Palette в правом верхнем окне) компонент JPopupMenu, и перетащим его на экранную форму. Он там не появится, но в окне инспектора компонентов в дереве Other Components возникнет новый узел jPopupMenu1[JPopupMenu]. Если щёлкнуть по узлу, окажется, что кроме самого компонента jPopupMenu1 в нём ничего нет.

Щёлкнем правой кнопкой мыши по этому узлу, и в появившемся всплывающем меню выберем Add/JMenuItem.

Создание нового пункта всплывающего меню

После этого в дереве jPopupMenu1 возникнет узел jMenuItem1[JMenuItem], и в редакторе свойств компонентов можно задать значение свойству Text данного компонента. Введём текст “Выйти из программы”.

Узел jMenuItem 1 Свойства jMenuItem 1

Далее уже известным нам способом зададим обработчик нажатия на этот пункт меню – выберем во всплывающем меню, возникающем при щелчке правой кнопкой мыши по имени jMenuItem1 в окне Inspector, пункт Events/ Action/ ActionPerformed. А в обработчике напишем оператор выхода из программы

System.exit(0);

Мы пока только создали всплывающее меню, которое доступно в нашей форме, но ещё не назначили его никакому компоненту. Для того, чтобы назначить меню jPopupMenu1 кнопке JButton1, выделим её, и в редакторе свойств компонентов в пункте componentPopupMenu нажмём мышью стрелку вниз, разворачивающую выпадающий список. Кроме значения <none>, назначенного по умолчанию этому свойству для каждого компонента, там имеется имя jPopupMenu1. Его мы и выберем.

Теперь всплывающее меню, состоящее из одного пункта “ Выйти из программы ”, появится при щелчке правой кнопкой мыши по кнопке. Добавление других пунктов меню и назначение им обработчиков событий проводится абсолютно так же, как для jMenuItem1.

2.12. Создание нового класса

Пусть мы хотим создать в нашем проекте новый класс. Для этого щёлкнем правой кнопкой мыши по имени нашего пакета, и выберем в появившемся всплывающем окне пункт New/ Java Class…

Создание нового класса. Шаг 1.

Создание нового класса. Шаг 2.

Появится диалоговое окно создания нового класса Java. В нём следует задать имя создаваемого класса, заменив имя по умолчанию. Зададим имя Figure.

В качестве пакета, в котором расположен класс, будет автоматически задан пакет нашего приложения (если первоначальный щелчок правой клавишей был по имени этого пакета).

Кроме описанной выше процедуры для создания нового класса можно воспользоваться мастером создания нового класса в главном меню среды NetBeans (File/New File…/Java Classes/Next>). В результате появится то же диалоговое окно, но в выпадающем списке придётся выбрать имя пакета .

После нажатия на кнопку Finish (“закончить”) в редакторе исходного кода появляется заготовка класса.

Заготовка нового класса.

Если в класс требуется добавить метод, поле данных или конструктор, можно это делать вручную. Но удобнее добавлять методы с помощью среды разработки.

Добавление в класс метода.Шаг 1.

Щелчок правой клавиши мышки в области надписи Methods и выбор пункта Add Method… всплывающего окна приводит к появлению диалога, в котором можно путём установки галочек и выбора пунктов выпадающего меню задавать нужные параметры метода

.

Добавление в класс метода. Шаг 2.

Аналогичным образом добавляются новые поля (Fields) и конструкторы (Constructors), но щелчок правой клавишей мыши должен делаться в области надписей Fields или Constructors.

2.13. Документирование исходного кода в Java

Одной из важнейших частей написания программного обеспечения является документирование создаваемого кода. В Java для этих целей применяется средство, обеспечивающее поддержку на уровне синтаксиса языка программирования – специализированные комментарии. Они начинаются с комбинации символов /** и заканчиваются комбинацией символов */

Часть комментариев автоматически создаёт среда разработки.

Пример:

/**

* Creates new form GUI_application

*/

Средством обработки внедрённых в исходный код комментариев и создания для класса справочных HTML-файлов является инструмент javadoc, входящий в состав JDK. Но в среде NetBeans удобнее пользоваться вызовом через главное меню: Build/Generate Javadoc for “…”.

Документационные комментарии бывают для:

· Пакетов (пока не функционируют).

· Классов.

· Интерфейсов.

· Пользовательских типов-перечислений (на уровне пакетов пока не функционируют, но можно использовать для типов, заданных в классах).

· Методов.

· Переменных.

Документационные комментарии пишутся непосредственно перед заданием соответствующей конструкции – пакета, класса, интерфейса, типа-перечисления, метода или переменной. Следует учитывать, что по умолчанию документация создаётся только для элементов, имеющих уровень видимости public или protected.

Пример фрагмента кода с документационными комментариями:

/**

* Пример приложения Java с документационными комментариями <br>

* В приложении заданы типы-перечисления Monthes и Spring и показано,

* как с ними работать.

* Кроме того, дан пример использования класса из другого пакета.

* @see enumApplication.Monthes Информация о типе-перечислении Monthes

* @see enumApplication.Spring

* @see enumApplication#m1

* @version Версия 0.1 Первоначальная версия, проверено при компиляции

* в среде NetBeans 5.5

* @author Вадим Монахов

*/

public class enumApplication extends javax.swing.JFrame {

int i=1;

/**

* Spring - задаёт перечисление из 3 весенних месяцев года: march,apr,may.

* <ul>

* <li>march

* <li>apr

* <li>may

* </ul>

* Идентификатор для марта записан отличающимся от соответствующего

* идентификатора в перечислении Monthes, а для апреля и мая записаны так

* же - чтобы подчеркнуть, что их пространства имён независимы.

*/

public enum Spring {march,apr,may};

/**

* Monthes - задаёт перечисление из 12 месяцев года: <br>

* jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec <br>

* (январь, февраль и т.д.)

*/

public enum Monthes {jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec};

Spring spr1= Spring.apr, spr2;

/**

*Переменная, иллюстрирующая работу с перечислениями

*/

public Monthes m1,m2=Monthes.mar,m3;

Имеется два типа кода внутри блока документационного комментария – HTML-текст и метаданные (команды документации, начинающиеся с символа @ ). Если пишется обычный текст, он рассматривается как HTML-текст, поэтому все пробелы и переносы на новую строку при показе приводятся к одному пробелу. Для того, чтобы очередное предложение при показе начиналось с новой строки, следует вставить последовательность символов <br> , называющуюся тегом HTML. Возможно использование произвольных тегов HTML, а не только тега переноса на новую строку: теги неупорядоченного списка <ul> и <li>, теги гиперссылок, изображений и т.д. В то же время не рекомендуется использовать заголовки и фреймы, поскольку это может привести к проблемам – javadoc создаёт на основе документационного кода собственную систему заголовков и фреймов. Кроме того, при преобразовании в HTML-документ из документационного кода удаляются символы “*”, если они стоят на первом значимом месте в строке (символы пробелов не являются значимыми).

Для более подробного изучения тегов HTML следует читать справочную или учебную литературу по этому языку разметки документов. Соответствующие ссылки и документы можно найти, например, на сайте автора

http://barsic.spbu.ru/ www/comlan/html_r.html

Команды документации (символы метаданных):

· @see (“смотри”) – применяется для создания в документе гиперссылок на другие комментарии. Можно использовать для любых конструкций (классов, методов и т.д. ). Формат использования: @see ИмяКласса – для класса; @see ИмяКласса.ИмяПеречисления – для типа-перечисления, заданного в классе; @see ИмяКласса#ИмяЧлена – для метода или переменной; для интерфейса – аналогично классу. При этом имя класса или интерфейса может быть либо коротким, либо квалифицировано именем пакета.

· @version (“версия”) – информация о версии. Используется для классов и интерфейсов. Формат использования: @version Информация о версии в произвольной форме.

· @author (“автор”) - Информация об авторе. Используется для классов и интерфейсов. Формат использования: @author Информация об авторе в произвольной форме. Может включать не только имя, но и данные об авторских правах, а также об электронной почте автора, его сайте и т.д.

· @since (“начиная с”) - Информация о версии JDK, начиная с которой введён или работоспособен класс или интерфейс. Формат использования: @since Информация в произвольной форме.

· @param (сокращение от parameter -“параметр”) - информация о параметре метода. Комментарий /** @param … */ ставится в месте декларации метода в списке параметров перед соответствующим параметром. Формат использования: @param ИмяПараметра Описание.

· @return (“возвращает”) - информация о возвращаемом методом значении и его типе. Формат использования: @return Информация в произвольной форме.

· @throws (“возбуждает исключение”) - информация об исключительных ситуациях, которые могут возбуждаться методом. Формат использования: @throws ИмяКлассаИсключения Описание.

· @deprecated (“устаревшее”) - информация о том, что данный метод устарел и в последующих версиях будет ликвидирован. При попытке использования таких методов компилятор выдаёт программисту предупреждение (warning) о том, что метод устарел, хотя и компилирует проект. Формат использования: @deprecated Информация в произвольной форме.

Признаком окончания команды документации является начало новой команды или окончание комментария.

Пример документации, созданной для пакета, из которого взят приведённый выше фрагмент кода:

Головная страница файлов документации

Страница описания элементов пакета java _ enum _ pkg

Страница описания класса enumApplication

Обратите внимание, что в краткой сводке (summary) приводятся только начальные строки соответствующей информации по элементам пакета или класса. Полную информацию можно прочитать после перехода по гиперссылке в описании соответствующего элемента. Поэтому важно, чтобы первые 2-3 строки информации содержали самые важные сведения.

2.14. Основные компоненты пакетов swing и awt

Пока мы научились работать только с формами, кнопками и всплывающими меню. Перечислим ещё ряд полезных компонентов.

Во-первых, следует остановиться на том, что в палитре компонентов NetBeans предлагается три категории компонентов: из библиотеки Swing (пакет swing), библиотеки AWT (пакет awt), и категория Beans. В Sun Java Studio Enterprise имеется ещё одна категория – Layouts, “менеджеры размещения”, - компоненты, отвечающие за способ расположения и выравнивания компонентов на форме.

Библиотека Swing является основной для большинства современных графических приложений Java. В ней предлагаются следующие компоненты (перечислены в том порядке, в каком они возникают в палитре компонентов):

Компонент

Назначение компонента

1

JLabel

“Метка” – вывод однострочного неформатированного текста

2

JButton

“Кнопка” – кнопка с текстом и/или с картинкой

3

JToggleButton

“Защёлкивающаяся кнопка” – кнопка с фиксацией. Может быть одной из нескольких таких кнопок в группе, в этом случае нажатие одной кнопки вызывает отпускание другой. Работа группы обеспечивается компонентом ButtonGroup, который должен быть перетащен на форму, а затем назначен свойству buttonGroup.

4

JCheckBox

“Чекбокс” - пункт выбора с независимой фиксацией.

5

JRadioButton

“Радиокнопка” - пункт выбора с зависимой фиксацией, должен быть одним из нескольких в группе. Работа группы обеспечивается компонентом ButtonGroup.

6

ButtonGroup

Обеспечивает работу групп компонентов JToggleButton или JradioButton.

7

JComboBox

“Комбобокс” – выпадающий список.

8

JList

Прокручивающийся список.

9

JTextField

“Текстовое поле” – однострочный пункт ввода и редактирования текста.

10

JTextArea

“Текстовая область” – многострочный пункт ввода и редактирования текста.

11

JPanel

“Панель” – группирующий компонент, позволяющий располагать на себе другие компоненты. Передвижение панели перемещает вместе с ней все расположенные на ней компоненты. По умолчанию свойство layout (“размещение”) установлено как FlowLayout – “в виде потока”. Для простых задач вместо этого компонента лучше использовать JLayeredPane.

12

JTabbedPane

“Панель с закладками” – каждый положенный на неё компонент показывается в отдельной закладке. Чтобы разместить на одной закладке несколько компонентов, сначала положите на панель с закладками обычную панель. Для того, чтобы создать последующие закладки, выделите панель с закладками, вызовите правой кнопкой мыши всплывающее меню, пункт Add From Palette (“добавить из палитры”), и добавьте ещё одну панель или другой компонент.

13

JScrollBar

Независимая полоса прокрутки. Используется редко – для программно управляемой прокрутки содержимого компонентов, для которых отсутствуют встроенные полосы прокрутки.

14

JScrollPane

“Панель с полосами прокрутки”

15

JMenuBar

“Меню формы” – предназначено для расположения в нём компонентов типа JMenu (заголовков меню).

16

JPopupMenu

“Всплывающее меню” - предназначено для расположения в нём компонентов типа JMenuItem (пунктов меню).

17

JSlider

"Ползунок". Используется для плавной регулировки числовых величин, а также связанных с ними программно регулируемых изменений.

18

JProgressBar

“Прогрессбар” – полоса показа доли выполнения задачи. Показывает уровень, отражающий долю выполнения задачи

19

JSplitPane

“Панель с разделителем” – панель, состоящая из двух частей, между которыми имеется линия разделителя, которую можно перетаскивать мышью, меняя взаимный размер частей.

20

JFormattedTextField

“Поле ввода форматированного текста”

21

JPasswordField

“Поле ввода пароля” – вводимый текст отображается звёздочками.

22

JSpinner

“Спиннер” - поле ввода числа с кнопками увеличения/ уменьшения.

23

JSeparator

“Сепаратор” – разделительная линия. Используется в декоративных целях для разделения рабочих областей формы и других группирующих компонентов.

24

JTextPane

“Текстовая панель”. По умолчанию автоматически переносит текст на новую строку. А не располагает в одну строку с показом горизонтального скроллера, как это делает JTextArea.

25

JEditorPane

“Панель текстового редактора”

26

JTree

“Дерево” – показывает дерево, в котором каждая ветвь может быть с иконками и текстом, а узлы разворачиваются и сворачиваются.

27

JTable

“Таблица” – показ текстовой таблицы. Имеет возможность заполнения значениями по умолчанию на этапе проектирования.

28

JToolBar

“Тулбар” – панель инструментов. Обычно на нём размещают кнопки JToggleButton, для которых назначены иконки.

29

JInternalFrame

“Дочернее окно” – окно многооконного приложения. Его можно перемещать в пределах родительского окна – главного окна приложения. В настоящее время такой стиль приложений практически не используется.

30

JLayeredPane

“Панель с абсолютным позиционированием элементов”

31

JDesktopPane

“Панель – рабочий стол”. Ещё один тип панели с абсолютным позиционированием элементов.

32

JOptionPane

“Диалоговая панель” – предназначена для показа диалоговых форм. В отличие от большинства других компонентов работа идёт с помощью методов класса. Имеются вызовы диалогов:

  • С сообщением:

javax.swing.JOptionPane.showMessageDialog(null,

"Кнопку нажали");

JOptionPane.showMessageDialog(null,"Привет!", "Заголовок сообщения", JOptionPane.INFORMATION_MESSAGE);

  • С подтверждением:

int option=javax.swing.JOptionPane.showConfirmDialog(

null,"Продолжить?");

Проверка, какую кнопку нажали или диалог закрыли без осуществления выбора, осуществляется сравнением с константами javax.swing.JOptionPane.NO_OPTION, CANCEL_OPTION, CLOSED_OPTION, OK_OPTION, YES_OPTION

  • С предложением ввести значение:

String input=javax.swing.JOptionPane.showInputDialog(

null,"Введите значение:");

- при отказе от ввода возвращается null.

Первый параметр – имя формы, в которой показывается диалог. Если он null – используется форма по умолчанию (главная форма приложения).

Существуют варианты указанных выше методов, позволяющие при вызове задавать дополнительные параметры диалога (заголовок, надписи на кнопках и др.).

33

JColorChooser

“Диалог выбора цвета” – предназначен для выбора пользователем цвета.

34

JFileChooser

“Диалог выбора файла” – предназначен для выбора пользователем файлов. Перед использованием требуется положить его на какую-нибудь диалоговую форму (JDialog, JFrame ) или какой-нибудь группирующий компонент формы.

35

JFrame

“Экранная форма”. Показывается вызовом вида jFrame1.setVisible(true);

36

JDialog

“Диалоговая форма”. Показывается вызовом вида jDialog1.setVisible(true);

Очень часто в приложении требуется вывести служебную информацию. В старых версиях Java для этого служил вызов System.out.println(“Текст сообщения”). В учебных проектах и при выводе отладочной информации этот метод до сих пор удобен. Но предоставлять таким образом информацию конечному пользователю представляется анахронизмом. Для выдачи пользователю информационного сообщения лучше использовать вызов

JOptionPane.showMessageDialog(null,"Привет!","Заголовок сообщения",

JOptionPane.INFORMATION_MESSAGE);

Если требуется вывести предупреждение об ошибке, последний параметр должен иметь значение JOptionPane.ERROR_MESSAGE, другое предупреждение - JOptionPane.WARNING_MESSAGE , вопрос - JOptionPane.QUESTION_MESSAGE. Наконец, если не требуется сопровождать вопрос иконкой на диалоговой панели, параметр должен быть JOptionPane.PLAIN_MESSAGE.

Библиотека компонентов AWT (Abstract Window Toolkit - Абстрактный Инструментарий графического Окна) является устаревшей по сравнению с библиотекой Swing, хотя сам пакет awt до сих пор является основой графики Java. В библиотеке AWT имеются практически те же компоненты, что и в Swing, но в меньшем количестве и в более примитивном варианте - с худшим дизайном и меньшей функциональностью.

Единственный компонент AWT, у которого нет прямого аналога в Swing – компонент типа Canvas – “холст для рисования”. Он обеспечивал вывод графических примитивов. Например, следующим образом:

java.awt.Graphics g=canvas1.getGraphics();

g.drawLine(10,10,100,100);

В Swing для этих целей можно рисовать по любому компоненту, например, по панели, или даже по кнопке:

java.awt.Graphics g=jPanel1.getGraphics();

g.drawLine(10,10,100,100);

g=jButton3.getGraphics();

g.drawLine(10,10,100,100);

Ещё одна категория, на которой следует остановиться, это компоненты Layout – менеджеры размещения. Разработчики Java предложили оригинальную, но очень неоднозначную идею организации расположения компонентов на форме. Вместо того, чтобы явно указывать позиции компонентов на этапе проектирования или работы программы, и использовать якоря (anchors) для привязки краёв компонентов к краям группирующего компонента, как это делается в других языках программирования, предлагается использовать тот или иной менеджер размещения. При изменении размера формы взаимное расположение компонентов будет меняться в зависимости от типа менеджера. Например, “обычное” размещение с фиксированным положением достигается с помощью размещения на форме менеджера AbsoluteLayout. В NetBeans это делается через пункт Set Layout всплывающего меню, как показано на рисунке. По умолчанию действует режим Free Design - “свободный дизайн”. Если установить менеджер размещения AbsoluteLayout, в редакторе свойств компонентов оказываются доступны свойства x и y – координаты компонентов.

Использовать якоря всё же можно, но с ограниченными возможностями и только в менеджере размещения Free Design – в других менеджерах они не работают. Для использования якоря следует щёлкнуть с помощью правой клавиши мыши по компоненту, расположенному на форме (например, кнопке), и в появившемся меню выбрать пункт Anchors. Якорь привязывает компонент к соответствующей стороне формы.

Выбор менеджера размещения

Установка привязки к краям формы – якорей

Left – привязка к левому краю формы, Right – к правому, Top- к верхнему, Bottom – к нижнему. По умолчанию менеджер сам выбирает варианты привязки, показывая их пунктирными линиями.

2.15. Технологии Java и .Net

Язык Java был создан в 1995 году как платформо-независимый язык прикладного программирования. Он очень быстро приобрёл широкую популярность, и заметно потеснил языки C и C++ в области разработки прикладного программного обеспечения. В результате стали говорить о технологии Java и о платформе Java, подчёркивая, что это больше, чем просто язык программирования. В 1998 году появилась компонентная модель Java Beans, и ряд сред разработки приложений Java стал успешно конкурировать со средами, обеспечивающими визуальное проектирование пользовательского интерфейса – Microsoft Visual BASIC и Borland Delphi. Казалось, что язык Java завоевал лидирующие позиции в области прикладного программирования.

Но в 2000 году Microsoft была предложена новая технология, названная .Net, в большой степени вобравшая в себя основные черты технологии Java: динамическую объектную модель, повышенную безопасность приложений (в том числе обеспечиваемую использованием ссылок и сборщика мусора), использование виртуальной машины и платформо-независимого байтового кода. Но технология .Net имела ряд новых черт.

Во-первых, вместо одного языка программирования в .Net стало возможно использование произвольного числа языков программирования. От них требовалось только, чтобы они удовлетворяли спецификации, позволяющей скомпилированным классам работать под управлением виртуальной машины, называемой в .Net Common Language Environment или Common Language Runtime – общей исполняющей средой поддержки языков программирования. Базовым языком программирования стал созданный одновременно с .Net язык C# - фактически, явившийся усовершенствованным вариантом языка Java, но несовместимый с ним как по ряду синтаксических конструкций, так и по скомпилированному коду.

Во-вторых, если Java рассматривался всеми в качестве языка программирования, то технология .Net фактически создавалась как платформо-независимая часть операционной системы MS Windows® . Поэтому важной частью .Net стал набор базовых классов .Net Framework, обеспечивающий поддержку прикладного программирования в большинстве практически важных областей.

В .Net основой программирования, как и в Java, служат классы. Исходный код класса, написанный на любом из языков .Net (то есть удовлетворяющий спецификации Common Language Environment), компилируется в платформо-независимый код. Этот код уже не имеет специфики языка программирования, на котором был написан, работает под управлением исполняющей среды .Net и может использоваться любыми другими классами .Net. Причём скомпилированный код класса может использоваться не только для вызовов, но и для наследования и обеспечения полиморфизма. Такие классы называются компонентами . Важно то, что для использования каким-либо приложением необходимого класса .Net Framework как при разработке приложения, так и при его запуске на компьютере пользователя нет необходимости загружать класс через Интернет или устанавливать на компьютере каким-либо другим образом. Достаточно того, чтобы был установлен свободно распространяемый пакет компонентов .Net Framework, что делается в версиях MS Windows® начиная с Windows® XP непосредственно во время установки операционной системы. Причём набор компонентов в пакете стандартизован, что обеспечивает гарантированное нахождение нужного компонента и его работоспособность. Именно эти особенности обеспечивают преимущество оболочки операционной системы по сравнению с отдельными программами и пакетами.

То, что технология .Net была сделана открытой и стандартизирована ISO (International Standard Organization – Международная Организация по Стандартам) в 2004 году, безусловно, сделало её привлекательной для многих разработчиков. Появление проекта Mono с реализацией .Net под Linux, а также ряда других проектов по реализации .Net под разными операционными системами позволило этой технологии выйти за пределы семейства операционных систем одной фирмы и сделало позиции Java неконкурентоспособными в данной области. Действительно, язык программирования – это одно, а оболочка операционной системы с набором большого числа компонентов – совсем другое. Тем более, что язык Java стал одним из возможных языков .Net, то есть вошёл в эту технологию как составная часть.

Как это ни удивительно, в рамках технологии Java удалось найти достойный ответ на вызов со стороны .Net . Им стала платформа NetBeans и идеология Open Source (“Открытый исходный код”).

NetBeans – это технология компонентного программирования, созданная на основе модели Java Beans, о которой речь пойдёт позже. Помимо набора компонентов в состав платформы NetBeans входит свободно распространяемая среда разработки NetBeans, позволяющая создавать различные типы программ на языке Java, в том числе – с использованием компонентов NetBeans, а также создавать такие компоненты.

Движение Open Source, набирающее популярность в последние годы, стремится к всеобщей открытости программного кода. При этом следует отличать два варианта открытости. Первый из них (freeware – свободно распространяемое программное обеспечение) подразумевает свободное распространение и использование программ и их исходных кодов, как правило, с единственным ограничением – сохранением открытости и свободы распространения программ и исходных кодов программных продуктов, использующих этот исходный код. Второй требует открытости исходного кода для изучения и, при необходимости, исправления ошибок, но не означает передачи авторских прав на какое-либо другое использование этого исходного кода.

Среда и компоненты NetBeans распространяются на основе соглашения Sun open licence (“Открытая лицензия Sun”). Эта лицензия позволяет свободно использовать среду и компоненты NetBeans для создания программного обеспечения, как свободно распространяемого, так и коммерческого, но требует, чтобы исходные коды создаваемых программ были открыты для просмотра.

Мультиплатформенность и наличие большого количества свободно распространяемых компонентов NetBeans в сочетании с качественной бесплатной средой разработки и очень широким использованием языка Java даёт возможность надеяться, что NetBeans сможет стать унифицированной оболочкой различных операционных систем. Но для серьёзного соперничества с .Net потребуется наличие стандартизированных пакетов компонентов, одной библиотеки Swing мало. Более того, необходимо, чтобы все эти пакеты входили в поставку JDK. Наличие разрозненных нестандартизированных пакетов не даст преимуществ перед конкурирующей технологией .Net.

Одним из решений этой проблемы стало расширение базового набора пакетов и классов в составе JDK. Даже самый старый пакет java в новых версиях JDK усовершенствуется, не говоря уж о более новом пакете javax. Кроме того, в поставке NetBeans Enterprise Pack имеется большое число дополнительных библиотечных пакетов.

Краткие итоги по главе 2

- Три базовых принципа объектно-ориентированного программирования: инкапсуляция , наследование , полиморфизм .

- Класс – это описание того, как устроен объект . И поля данных , и методы задаются в классах. Но при выполнении программы поля данных хранятся в объектах, а методы – в классах. Методы задают поведение объекта, а поля данных - состояние объекта.

- Переменные, описываемые в классах, называются глобальными . Они задают поля данных объектов. Переменные, описываемые в методах, называются локальными . Они являются вспомогательными и существуют только во время вызова метода.

- Переменные ссылочного типа содержат адреса данных, а не сами данные. Поэтому присваивания для таких переменных меняют адреса, но не данные. Все объектные типы являются ссылочными. Потеря ссылки на объект приводит к сборке мусора.

- Объект создаётся с помощью вызова конструктора - специальной подпрограммы-функции, задаваемой в классе.

- Методы делятся на методы объектов и методы классов . Метод объекта можно вызывать только из объекта соответствующего типа. А метод класса может работать и при отсутствии объекта, и вызываться из класса.

- При декларации класса можно указывать, что он общедоступен, с помощью модификатора доступа public. В этом случае возможен доступ к данному классу из других пакетов. В файле .java можно располагать только один общедоступный класс и произвольное число классов с другим уровнем видимости. Если модификатор public отсутствует, то доступ к классу разрешён только из классов, находящихся с ним в одном пакете. Про такие файлы говорят, что у них пакетный вариант доступа.

- Важнейшими пакетами являются java и javax, а также вложенные в них пакеты. Информацию о содержащихся в них элементах можно получить в среде разработки, набрав java. или javax. И прочитав появившуюся подсказку.

- Все классы и объекты приложения вызываются и управляются из метода main, который имеет сигнатуру public static void main(String[] args). Он является методом класса, и поэтому для его работы нет необходимости в создании объекта, являющегося экземпляром класса.

- Визуальное проектирование приложения с графическим интерфейсом пользователя (GUI) происходит в режиме Design. Как правило, основой для построения такого интерфейса служат компоненты Swing.

- Документирование исходного кода в Java осуществляется с помощью специальных документационных комментариев /** Текст комментария в формате HTML */ . Также имеется ряд команд документации, начинающихся с символа @ .Утилита javadoc позволяет по документационным комментариям создавать систему HTML-страниц с документацией о пакетах и классах.

- Для выдачи пользователю информационного сообщения следует использовать вызов JOptionPane.showMessageDialog(null,"Привет!","Заголовок сообщения", JOptionPane.INFORMATION_MESSAGE).

Типичные ошибки:

  • Очень часто встречающаяся ошибка: путают классы, объекты и объектные переменные. Но это совершенно разные сущности. Класс – это тип, то есть описание того, как устроена ячейка памяти, в которой будут располагаться поля данных объекта, и какие методы можно вызывать. Объект – это содержимое ячейки памяти объектного типа. А в переменной объектного типа содержится адрес объекта.
  • Ошибочно считают, что методы хранятся в объектах.
  • Пытаются обратиться к объекту с помощью ссылочной переменной, которой назначено значение null.
  • Непреднамеренная потеря связи с объектом. Обычно возникает при изменении ссылки на объект внутри подпрограммы.
  • При работе с радиокнопками JRadioButton или кнопками JToggleButton забывают назначить им группу ButtonGroup.

Задания

  • Создать новый проект NetBeans как Java Application. Импортировать классы пакета swing. В методе main вызвать диалоговую панель JOptionPane с каким-либо сообщением. Например, “Привет всем!”.
  • На основе проекта с имеющимся кодом – заготовки приложения с графическим интерфейсом, создать приложение с кнопкой “OK”, закрывающей приложение, и кнопкой “Нажми меня!”, вызывающей при нажатии диалоговую панель с сообщением “Меня нажали”.
  • Переименовать пункты меню приложения , переведя их на русский язык.
  • Добавить в класс приложения общедоступное числовое поле x, инициализированное неким значением, и поле y того же типа, но без инициализации. Добавить кнопку, вызывающую диалоговую панель с сообщением о значениях полей x и y.
  • Создать документационные комментарии для поля x и методов – обработчиков событий нажатия на кнопки. Вызвать генерацию документации для проекта, просмотреть в ней созданные комментарии.

Глава 3. Примитивные типы данных и операторы для работы с ними

3.1.Булевский (логичес кий) тип

Величины типа boolean принимают значения true или false.

Объявление булевских переменных:

boolean a;

boolean b;

Использование в выражениях при присваиваниях:

a=true;

b=a;

Булевские величины обычно используются в логических операторах и в операциях отношения.

Логические операторы

Оператор

Название

Пример

&&

логическое "И" (and)

a&&b

||

логическое "ИЛИ" (or)

a||b

^

логическое "исключающее ИЛИ" (xor)

a^b

!

логическое "НЕ" (not)

!a

Значением логического выражения являются true или false. Например, если a=true, b=true, то a && b имеет значение true. А при a=false или b=false выражение a && b принимает значение false.

Для работы с логическими выражениями часто применяют так называемые таблицы истинности. В них вместо логической единицы (true) пишут 1, а вместо логического нуля (false) пишут 0. В приведённой ниже таблице указаны значения логических выражений при всех возможных комбинациях значений a и b.

a

0

0

1

1

b

0

1

0

1

Выражение

Значения

a &&b

0

0

0

1

a ||b

0

1

1

1

a ^b

0

1

1

0

!a

1

1

0

0

Выполнение булевских операторов происходит на аппаратном уровне, а значит, очень быстро. Реально процессор оперирует числами 0 и 1, хотя в Java это осуществляется скрытым от программиста образом.

Логические выражения в Java вычисляются в соответствии с так называемым укороченным оцениванием: из приведённой выше таблицы видно, что если a имеет значение false, то значение оператора a&&b будет равно false независимо от значения b. Поэтому если b является булевским выражением, его можно не вычислять. Аналогично, если a имеет значение true, то значение оператора a||b будет равно true независимо от значения b.


Операции отношения

Это операторы сравнения и принадлежности. Они имеют результат типа boolean. Операторы сравнения применимы к любым величинам a и b одного типа, а также к произвольным числовым величинам a и b, не обязательно имеющим один тип.

Оператор

Название

Пример

==

равно

a==b

!=

не равно

a!=b

>

больше

a>b

<

меньше

a<b

>=

больше или равно

a>=b

<=

меньше или не равно

a<=b

instanceof

Принадлежность

объекта классу

obj instanceof MyClass

Про оператор instanceof будет рассказано в разделе, посвящённом динамической проверке типов.

3.2.Целые типы, переменные, константы

Тип

Число байт

Диапазон значений

Описание

byte

1

-128..127

Однобайтовое целое число

(8-битное целое со знаком)

short

2

-215 ..215 -1 =

- 32768.. 32767

Короткое целое число

(16- битное целое со знаком)

char

2

\u0000..\uFFFF=0.. 65535

Символьный тип

(беззнаковое 16- битное целое)

int

4

-231 ..231 -1 =

- 2.147483648*109 ..

2.147483647*109

Целое число

(32- битное целое со знаком)

long

8

-263 ..263 -1 =

-9.22337203685478·1018 ..

9.22337203685478·1018

Длинное целое число

(64- битное целое со знаком)

Для задания в тексте программы численных литерных констант типа long, выходящих за пределы диапазона чисел типа int, после написания числа следует ставить постфикс – букву L. Например, 600000000000000L. Можно ставить и строчную l, но её хуже видно, особенно – на распечатках программы (можно перепутать с единицей). В остальных случаях для всех целочисленных типов значение указывается в обычном виде, и оно считается имеющим тип int – но при присваивании число типа int автоматически преобразуется в значение типа long.

Как уже говорилось, объявление переменных может осуществляться либо в классе, либо в методе.

В классе их можно объявлять как без явного присваивания начального значения, так и с указанием этого значения. Если начальное значение не указано, величина инициализируется нулевым значением. Если объявляется несколько переменных одного типа, после указания имени типа разрешается перечислять несколько переменных, в том числе – с присваиванием им начальных значений.

В методе все переменные перед использованием обязательно надо инициализировать – автоматической инициализации для них не происходит. Это надо делать либо при объявлении, либо до попытки использования значения переменной в подпрограмме. Попытка использования в подпрограмме значения неинициализированной переменной приводит к ошибке во время компиляции.

Рассмотрим примеры задания переменных в классе.

int i,j,k;

int j1;

byte i1,i2=-5;

short i3=-15600;

long m1=1,m2,m3=-100;

Заметим, что после указанных объявлений переменные i,j,k,j1,i1,m2 имеют значение 0. Для i1 это неочевидно – можно подумать, что обе переменные инициализируются значением -5. Поэтому лучше писать так:

byte i1=0,i2=-5;

Использование в выражениях:

i=5;

j=i*i + 1

m1=j

m2=255;

m1=m1 + m2*2;

Тип char в Java, как и в C/C++, является числовым , хотя и предназначен для хранения отдельных символов. Переменной символьного типа можно присваивать один символ, заключённый в одинарные кавычки, либо кодирующую символ управляющую последовательность Unicode. Либо можно присваивать числовой код символа Unicode (номер символа в кодовой таблице):

char c1='a';

char c2='\u0061';

char c3=97;

Все три приведённые декларации переменных присваивают переменным десятичное значение 97, соответствующее латинской букве “a”.

Существуют различные кодовые таблицы для сопоставления числам символов, которые могут быть отображены на экране или другом устройстве. В силу исторических причин самой распространённой является кодовая таблица ASCII для символов латиницы, цифр и стандартных специальных символов. Поэтому в таблице Unicode им были даны те же номера, и для них коды Unicode и ASCII совпадают:

'A' имеет код 65, 'B' – 66, 'Z' – 90, 'a' – 97, 'z' - 122, '0' - 48, '1' - 49, '9' – 57,

':' – 58, ';' – 59, '<' – 60, '=' – 61, '>' – 62, и так далее.

К сожалению, с переменными и значениями символьного типа можно совершать все действия, которые разрешено совершать с целыми числами. Поэтому символьные значения можно складывать и вычитать, умножать и делить не только на “обычные” целые величины, но и друг на друга! То есть присваивание с1='a'*'a'+1000/'b' вполне допустимо, несмотря на явную логическую абсурдность.

Константами называются именованные ячейки памяти с неизменяемым содержимым. Объявление констант осуществляется в классе, при этом перед именем типа константы ставится комбинация зарезервированных слов public и final:

public final int MAX1=255;

public final int MILLENIUM=1000;

Константами можно пользоваться как переменными, доступными только по чтению. Попытка присвоить константе значение с помощью оператора присваивания “=” вызывает ошибку компиляции.

Для того чтобы имена констант были хорошо видны в тексте программы, их обычно пишут в верхнем регистре (заглавными буквами).

Имеется следующее правило хорошего тона: никогда не используйте одно и то же числовое литерное значение в разных местах программы, вместо этого следует задать константу и использовать её имя в этих местах. Например, мы пишем программу обработки текста, в которой во многих местах используется литерная константа 26 – число букв в английском алфавите. Если у нас возникнет задача модифицировать её для работы с алфавитом, в котором другое число букв (например, с русским), придётся вносить исправления в большое число мест программы. При этом нет никакой гарантии, что не будет забыто какое-либо из необходимых исправлений, или случайно не будет “исправлено” на новое значение литерное выражение 26, не имеющее никакого отношения к числу букв алфавита. Оптимистам, считающим, что проблема решается поиском числа 26 по файлам проекта (в некоторых средах разработки такое возможно), приведу пример, когда это не поможет: символ подчёркивания “_” иногда (но не всегда) считается буквой. Поэтому в некоторых местах программы будет фигурировать число 27, а в некоторых 26. И исправления надо будет вносить как в одни, так и в другие места. Поэтому работа перестаёт быть чисто технической – при изменениях требуется вникать в смысл участка программы, и всегда есть шанс ошибиться.

Использование именованных констант полностью решают эту проблему. Если мы введём константу CHARS_COUNT=26, то вместо 27 будет записано CHARS_COUNT +1, и изменение значения CHARS_COUNT повлияет правильным образом и на это место программы. То есть достаточно внести одно изменение, и гарантированно получить правильный результат для всех мест программы, где необходимы исправления.

3.3.Основные операторы для работы с целочисленными величинами

Все перечисленные ниже операторы действуют на две целочисленные величины, которые называются операндами. В результате действия оператора возвращается целочисленный результат. Во всех перечисленных далее примерах i и j обозначают целочисленные выражения, а v – целочисленную переменную.

Оператор

Название

Пример

Примечание

+

Оператор сложения

i+j

В случае, когда операнды i и j имеют разные типы или типы byte, short или char, действуют правила автоматического преобразования типов.

Оператор вычитания

i-j

*

Оператор умножения

i*j

/

Оператор деления

i/j

Результат округляется до целого путём отбрасывания дробной части как для положительных, так и для отрицательных чисел.

%

Оператор остатка от целочисленного деления

i%j

Возвращается остаток от целочисленного деления

Оператор

Название

Пример

Примечание

=

Оператор присваивания

v=i

Сначала вычисляется выражение i, после чего полученный результат копируется в ячейку v

++

Оператор инкремента (увеличения на 1)

v++

v++ эквивалентно v=v+1

--

Оператор декремента (уменьшения на 1)

v--

v-- эквивалентно v=v-1

+=

v+=i

v+=i эквивалентно v=v+i

-=

v-=i

v-=i эквивалентно v=v-i

*=

v*=i

v*=i эквивалентно v=v*i

/=

v/=i

v/=i эквивалентно v=v/i

%=

v%=i

v%=i эквивалентно v=v%i

Также имеются важные методы классов Integer и Long, обеспечивающие преобразование строкового представления числа в целое значение:

Integer.parseInt(строка )

Long.parseLong(строка )

Например, если в экранной форме имеются текстовые пункты ввода jTextField1 и jTextField2, преобразование введённого в них текста в числа может проводиться таким образом:

int n=Integer.parseInt(jTextField1.getText());

long n1=Long.parseLong(jTextField2.getText());

Функции Integer.signum(число ) и Long.signum(число ) возвращают знак числа – то есть 1 если число положительно, 0, если оно равно 0, и -1 если число отрицательно.

Кроме того, в классах Integer и Long имеется ряд операторов для работы с числами на уровне их битового представления.

Классы Integer и Long являются так называемыми оболочечными классами (wrappers), о них речь пойдёт чуть дальше.

3.4 .Вещественные типы и класс Math

Тип

Размер

Диапазон

Описание

float

4 байта

(32 бит)

1.5*10-45 ..3.4*1038

“Одинарная” точность, 7-8 значащих десятичных цифр мантиссы.

Тип real*4 стандарта IEEE754

double

8 байт

(64 бит)

5*10-324 ..1.7*10308

“Двойная” точность, 15..16 значащих цифр мантиссы.

Тип real*8 стандарта IEEE754

Оператор

Название

Пример

Примечание

+

Оператор сложения

x+y

В случае, когда операнды x и y имеют разные типы, действуют правила автоматического преобразования типов.

Оператор вычитания

x-y

*

Оператор умножения

x*y

/

Оператор деления

x/y

Результат является вещественным. В случае, когда операнды x и y имеют разные типы, действуют правила автоматического преобразования типов.

%

Оператор остатка от целочисленного деления

x%y

Возвращается остаток от целочисленного деления x на y. В случае, когда операнды x и y имеют разные типы, действуют правила автоматического преобразования типов.

Оператор

Название

Пример

Примечание

=

Оператор присваивания

v=x

Сначала вычисляется выражение x, после чего полученный результат копируется в ячейку v

++

Оператор инкремента (увеличения на 1)

v++

++v

эквивалентно v=v+1

--

Оператор декремента (уменьшения на 1)

v--

--v

эквивалентно v=v-1

+=

v+=x

эквивалентно v=v+x

-=

v-=x

эквивалентно v=v-x

*=

v*=x

эквивалентно v=v*x

/=

v/=x

эквивалентно v=v/x

%=

v%=x

эквивалентно v=v%x

Математические функции, а также константы “пи” (Math.PI) и “е” (Math.E ) заданы в классе Math, находящемся в пакете java.lang .

Для того, чтобы их использовать, надо указывать имя функции или константы, квалифицированное впереди именем класса Math.

Например, возможны вызовы Math.PI или Math.sin(x). При этом имя пакета java.lang указывать не надо – он импортируется автоматически. К сожалению, использовать математические функции без квалификатора Math, не получается, так как это методы класса.

Константы в классе Math заданы так:

public static final double E = 2.7182818284590452354;

public static final double PI = 3.14159265358979323846;

Модификатор static означает, что это переменная класса; final означает, что в классе-наследнике переопределять это значение нельзя.

В приведённой ниже таблицы величины x , y , angdeg , angrad имеют тип double, величина a – тип float, величины m , n – целые типов long или int. Математические функции возвращают значения типа double, если примечании не указано иное.

Оператор класса Math

Примечание

Тригонометрические и обратные тригонометрические функции

sin(x)

sin(x) - синус

cos(x)

cos(x) - косинус

tan(x)

tg(x) - тангенс

asin(x)

arcsin(x) - арксинус

acos(x)

arccos(x) - арккосинус

atan(x)

arctg(x) - арктангенс

atan2(y, x)

Возвращает угол, соответствующий точке с координатами x , y , лежащий в пределах .

toRadians(angdeg)

angdeg / 180.0 * PI; - перевод углов из градусов в радианы.

toDegrees(angrad)

angrad * 180.0 / PI; - перевод углов из радиан в градусы.

Степени, экспоненты, логарифмы

exp(x)

ex - экспонента

expm1(x)

ex -1. При x, близком к 0, даёт гораздо более точные значения, чем exp(x)-1

log(x)

ln(x) – натуральный логарифм.

log10(x)

log10 (x) – десятичный логарифм.

log1p(x)

ln(1+x). При x, близком к 0, даёт гораздо более точные значения, чем log(1+x)

sqrt(x)

- квадратный корень

cbrt(x)

- кубический корень

hypot(x,y)

- вычисление длины гипотенузы по двум катетам

pow(x, y)

xy – возведение x в степень y

sinh(x)

sh(x)= – гиперболический синус

cosh(x)

ch(x)= – гиперболический косинус

tanh(x)

th(x)= – гиперболический тангенс

Модуль, знак, минимальное, максимальное число

abs(m)

abs(x)

Абсолютное значение числа. Аргумент типа int, long, float или double. Результат того же типа, что аргумент.

signum(a)

signum(x)

Знак числа. Аргумент типа float или double. Результат того же типа, что аргумент.

min(m,n)

min(x,y)

Минимальное из двух чисел. Аргументы одного типа. Возможны типы: int, long, float, double. Результат того же типа, что аргумент.

max(m,n)

max(x,y)

Максимальное из двух чисел. Аргументы одного типа. Возможны типы: int, long, float, double. Результат того же типа, что аргумент.

Округления

ceil(x)

Ближайшее к x целое, большее или равное x

floor(x)

Ближайшее к x целое, меньшее или равное x

round(a)

round(x)

Ближайшее к x целое. Аргумент типа float или double. Результат типа long, если аргумент double, и типа int – если float. То же, что (int)floor(x + 0.5).

rint(x)

Ближайшее к x целое.

ulp(a)

ulp(x)

Расстояние до ближайшего большего чем аргумент значения того же типа (“дискретность” изменения чисел в формате с плавающей точкой вблизи данного значения). Аргумент типа float или double. Результат того же типа, что аргумент.

Случайное число, остаток

random()

Псевдослучайное число в диапазоне от 0.0 до 1.0. При этом 0 ≤ Math.random() < 1.

IEEEremainder(x,y)

Остаток от целочисленного деления x / y , то есть x - y * n , где n – результат целочисленного деления

Также имеются методы оболочечных классов Float и Double, обеспечивающие преобразование строкового представления числа в значение типа Float или Double:

Float.parseFloat(строка )

Double.parseDouble(строка )

Например, если в экранной форме имеются текстовые пункты ввода jTextField1 и jTextField2, преобразование введённого в них текста в числа может проводиться таким образом:

float f1= Float.parseFloat(jTextField1.getText());

double d1= Double.parseDouble(jTextField2.getText());

Иногда вместо класса Math ошибочно пытаются использовать пакет java.math, в котором содержатся классы BigDecimal, BigInteger, MathContext, RoundingMode. Класс BigDecimal обеспечивает работу с десятичными числами с произвольным числом значащих цифр – в том числе с произвольным числом цифр после десятичной точки. Класс BigInteger обеспечивает работу с целыми числами произвольной длины. Классы MathContext и RoundingMode являются вспомогательными, обеспечивающими настройки для работы с некоторыми методами классов BigDecimal и BigInteger.

3.5 .Правила явного и автоматического преобразования типа при работе с числовыми величинами

Компьютер может проводить на аппаратном уровне целочисленные математические вычисления только с величинами типа int или long. При этом операнды в основных математических операциях ( + , - , * , / , % ) должны быть одного типа. Поэтому в тех случаях, когда операнды имеют разные типы, либо же типы byte, short или char, действуют правила автоматического преобразования типов: для величин типа byte, short или char сначала происходит преобразование в тип int, после чего производится их подстановка в качестве операндов. Если же один из операндов имеет тип long, действия производятся с числами типа long, поскольку второй операнд автоматически преобразуется к этому типу.

Аналогично, при работе с вещественными величинами в Java возможна работа на аппаратном уровне только с операндами типов float и double. При этом операнды в основных математических операциях должны быть одного типа. Если один из операндов имеет тип double, а другой float, действия производятся с числами типа double, поскольку операнд типа float автоматически преобразуется к типу double.

Если один из операндов целочисленный, а другой вещественный, сначала идёт преобразование целочисленного операнда к такому же вещественному типу, а потом выполняется оператор.

Рассмотрим теперь правила совместимости типов по присваиванию. Они просты: диапазон значений типа левой части не должен быть уже, чем диапазон типа правой. Поэтому в присваиваниях, где тип в правой части не умещается в диапазон левой части, требуется указывать явное преобразование типа . Иначе компилятор выдаст сообщение об ошибке с не очень адекватной диагностикой “possible loss of precision” (“возможная потеря точности”).

Для явного преобразования типа в круглых скобках перед преобразуемой величиной ставят имя того типа, к которому надо преобразовать. Например, пусть имеется

double d=1.5;

Величину d можно преобразовать к типу float таким образом:

(float)d

Аналогично, если имеется величина f типа float, её можно преобразовать в величину типа double таким образом:

(double)f

Во многих случаях к явному преобразованию типов прибегать не нужно, так как действует автоматическое преобразование, если переменной, имеющий тип с более широким диапазоном изменения, присваивается выражение, имеющее тип с более узким диапазоном изменения.

Например, для вещественных типов разрешено присваивание только в том случае, когда слева стоит вещественная переменная более широкого диапазона, чем целочисленная или вещественная – справа. Например, переменной типа double можно присвоить значение типа float, но не наоборот. Но можно использовать преобразование типов для того, чтобы выполнить такое присваивание. Например:

double d=1.5;

float f=(float)d;

Другие примеры допустимых присваиваний:

byte byte0=1; //-128..127

short short0=1;//- 32768.. 32767

char char0=1;//0.. 65535

int int0=1; //- 2.147483648E9.. 2.147483647E9

long long0=1;//-9.223E18.. 9.223E18

float float0=1;// ±(1.4E-45..3.402E38)

double double0=1;// ±(4.9E-324..1.797E308 )

short0=byte0;

byte0=(byte )short0;

char0=(char )short0;

int0=short0;

int0=char0;

char0=(char )int0;

short0=(short )int0;

long0=byte0;

byte0=(byte )long0;

long0=char0;

long0=int0;

int0=(int )long0;

float0=byte0;

float0=int0;

float0=(float )double0;

double0=float0;

3.6. Оболочечные классы. Упаковка (boxing) и распаковка (unboxing)

В ряде случаев вместо значения примитивного типа требуется объект. Например, для работы со списками объектов. Это связано с тем, что работа с объектами в Java может быть унифицирована, поскольку все классы Java являются наследниками класса Object, а для примитивных типов этого сделать нельзя.

Для таких целей в Java каждому примитивному типу сопоставляется объектный тип, то есть класс. Такие классы называются оболочечными (class wrappers). В общем случае они имеют те же имена, что и примитивные типы, но начинающиеся не со строчной, а с заглавной буквы. Исключение почему-то составляют типы int и char, для которых имена оболочечных классов Integer и Character.

Примитивный тип

Оболочечный класс

byte

Byte

short

Short

char

Character

int

Integer

long

Long

float

Float

double

Double