Java для всех [Алексей Васильев] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

А ле к с е й В а с и ль е в

JAVA

ДЛЯ ВСЕХ
К НИГА О П О П УЛ ЯР НОМ ЯЗЫК Е JAVA
О Т А В Т О РА КОМПЬ Ю Т Е Р НЫ Х БЕС Т С Е Л ЛЕ Р ОВ

Ещё больше книг по Java в нашем Телеграм канале
https://t.me/javalib

2020

ББК 32.973.2-018.1
УДК 004.43
В19

Васильев Алексей
В19 Java для всех. — СПб.: Питер, 2020. — 512 с.: ил. — (Серия «Библиотека программиста»).
ISBN 978-5-4461-1382-8
Java — один из самых популярных и востребованных языков в мире. Алексей Васильев — автор
многочисленных компьютерных бестселлеров — познакомит вас со всем необходимым для эффективной работы с этим языком. Вы изучите базовые типы, управляющие инструкции, особенности описания
классов и объектов в Java, создание интерфейсов, лямбда-выражения, обобщенные классы. Каждая
глава содержит примеры кода, которые в свою очередь снабжены как построчными пояснениями, так
и подробным разбором примера программы. Примеры, используемые в этой книге, пригодятся вам
в дальнейшей работе с языком Java. Программирование — это нестрашно! Даже если у вас нет никакого
опыта, вы с легкостью освоите Java, воспользовавшись уникальной методикой Алексея Васильева,
и перейдете на профессиональный уровень.

16+ (В соответствии с Федеральным законом от 29 декабря 2010 г. № 436-ФЗ.)

ББК 32.973.2-018.1
УДК 004.43

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

ISBN 978-5-4461-1382-8

© ООО Издательство «Питер», 2020
© Серия «Библиотека программиста», 2020

Оглавление

Вступление..............................................................................................................9
О книге и не только.................................................................................................. 9
Объектно-ориентированное программирование и Java............................................. 9
Особенности языка Java......................................................................................... 11
Java и другие языки программирования.................................................................. 12
Программное обеспечение..................................................................................... 14
Особенности книги................................................................................................. 16
Полезные ресурсы.................................................................................................. 17
Обратная связь....................................................................................................... 18
Благодарности........................................................................................................ 19
От издательства..................................................................................................... 19
Глава 1. Основы Java................................................................................................. 20
Простые программы............................................................................................... 20
Знакомство с переменными.................................................................................... 27
Базовые типы данных............................................................................................. 31
Приведение типов.................................................................................................. 33
Основные операторы.............................................................................................. 35
Использование основных операторов..................................................................... 42
Полет тела, брошенного под углом к горизонту................................................ 43
Вычисление скорости на маршруте................................................................... 45
Орбита спутника............................................................................................... 47
Комплексные числа........................................................................................... 48
Прыгающий мячик............................................................................................. 50

4   Оглавление
Решение тригонометрического уравнения......................................................... 52
Кодирование символов...................................................................................... 54
Расчет параметров цепи.................................................................................... 56
Резюме................................................................................................................... 58
Глава 2. Управляющие инструкции Java..................................................................... 60
Условный оператор if.............................................................................................. 60
Оператор выбора switch......................................................................................... 70
Оператор цикла for................................................................................................. 75
Оператор цикла while............................................................................................. 80
Оператор цикла do-while........................................................................................ 81
Использование управляющих инструкций............................................................... 83
Вычисление экспоненты.................................................................................... 83
Числа Фибоначчи.............................................................................................. 84
Вычисление числа π.......................................................................................... 85
Метод последовательных итераций................................................................... 89
Решение квадратного уравнения....................................................................... 91
Полет в атмосфере............................................................................................ 94
Резюме................................................................................................................. 100
Глава 3. Массивы..................................................................................................... 102
Одномерные массивы........................................................................................... 102
Двумерные и многомерные массивы..................................................................... 106
Символьные и текстовые массивы........................................................................ 111
Присваивание и сравнение массивов.................................................................... 117
Использование массивов...................................................................................... 123
Кодирование и декодирование текста............................................................. 123
Умножение векторов....................................................................................... 124
Числа Фибоначчи............................................................................................ 126
Работа с полиномами...................................................................................... 127
Сортировка массива........................................................................................ 129
Транспонирование квадратной матрицы......................................................... 131
Произведение квадратных матриц.................................................................. 133
Задача перколяции......................................................................................... 134
Резюме................................................................................................................. 140

Оглавление    5
Глава 4. Классы и объекты....................................................................................... 142
Знакомство с ООП................................................................................................ 142
Создание классов и объектов............................................................................... 147
Статические поля и методы.................................................................................. 152
Закрытые члены класса........................................................................................ 156
Ключевое слово this............................................................................................. 158
Внутренние классы............................................................................................... 160
Анонимные объекты............................................................................................. 162
Работа с классами и объектами............................................................................ 163
Схема Бернулли.............................................................................................. 163
Математические функции................................................................................ 166
Динамический список из объектов.................................................................. 171
Работа с матрицами........................................................................................ 173
Резюме................................................................................................................. 180
Глава 5. Методы и конструкторы.............................................................................. 182
Перегрузка методов............................................................................................. 182
Конструктор......................................................................................................... 187
Объект как аргумент и результат метода.............................................................. 191
Механизм передачи аргументов........................................................................... 194
Применение методов на практике........................................................................ 196
Интерполяционный полином........................................................................... 196
Геометрические фигуры.................................................................................. 201
Матричная экспонента.................................................................................... 205
Операции с векторами.................................................................................... 211
Операции с полиномами.................................................................................. 217
Бинарное дерево............................................................................................. 224
Резюме................................................................................................................. 229
Глава 6. Наследование............................................................................................. 230
Знакомство с наследованием................................................................................ 230
Наследование и закрытые члены.......................................................................... 233
Пакеты и защищенные члены............................................................................... 235
Конструкторы и наследование.............................................................................. 238

6   Оглавление
Переопределение методов................................................................................... 241
Замещение полей при наследовании.................................................................... 247
Многоуровневое наследование............................................................................. 249
Объектные переменные суперкласса.................................................................... 252
Абстрактные классы............................................................................................. 256
Анонимные классы............................................................................................... 258
Резюме................................................................................................................. 266
Глава 7. Интерфейсы и лямбда-выражения.............................................................. 268
Знакомство с интерфейсами................................................................................. 268
Интерфейсные переменные.................................................................................. 273
Расширение интерфейсов..................................................................................... 277
Анонимный класс на основе интерфейса.............................................................. 279
Лямбда-выражения и функциональные интерфейсы............................................. 284
Ссылки на методы................................................................................................ 291
Резюме................................................................................................................. 298
Глава 8. Работа с текстом......................................................................................... 300
Объекты класса String.......................................................................................... 301
Метод toString().................................................................................................... 305
Базовые операции с текстом................................................................................ 307
Сравнение текстовых строк.................................................................................. 309
Поиск символов и подстрок в тексте..................................................................... 311
Методы для работы с текстом............................................................................... 313
Форматированный текст....................................................................................... 316
Класс StringBuffer................................................................................................. 320
Класс StringBuilder................................................................................................ 326
Обработка текста................................................................................................. 328
Резюме................................................................................................................. 332
Глава 9. Обработка исключений............................................................................... 334
Исключительные ситуации................................................................................... 334
Классы исключений.............................................................................................. 336

Оглавление    7
Пример обработки исключений............................................................................ 339
Использование объекта исключения..................................................................... 341
Использование нескольких catch-блоков.............................................................. 343
Вложенные конструкции try-catch......................................................................... 346
Генерирование исключений.................................................................................. 351
Методы и контролируемые исключения................................................................ 354
Создание классов исключений.............................................................................. 355
Резюме................................................................................................................. 357
Глава 10. Многопоточное программирование........................................................... 359
Создание дочернего потока.................................................................................. 360
Управление потоками........................................................................................... 369
Фоновые потоки................................................................................................... 372
Создание нескольких потоков............................................................................... 373
Главный поток...................................................................................................... 376
Синхронизация потоков........................................................................................ 378
Резюме................................................................................................................. 383
Глава 11. Обобщенные типы.................................................................................... 384
Обобщенные методы............................................................................................ 384
Перегрузка обобщенных методов......................................................................... 393
Обобщенные классы............................................................................................. 395
Обобщенные интерфейсы..................................................................................... 400
Обобщенные классы и наследование.................................................................... 401
Ограничения на обобщенные параметры.............................................................. 403
Знакомство с коллекциями................................................................................... 406
Списки.................................................................................................................. 408
Множества........................................................................................................... 414
Резюме................................................................................................................. 417
Глава 12. Программы с графическим интерфейсом.................................................. 419
Создание простого окна....................................................................................... 420
Окно с кнопками и меткой.................................................................................... 425

8   Оглавление
Компоненты и события......................................................................................... 433
Создание графика функции.................................................................................. 440
Калькулятор......................................................................................................... 458
Резюме................................................................................................................. 466
Глава 13. Немного о разном..................................................................................... 468
Работа с файлами................................................................................................. 468
Аргументы командной строки............................................................................... 476
Методы с произвольным количеством аргументов................................................ 477
Цикл по коллекции............................................................................................... 481
Рекурсия.............................................................................................................. 483
Перечисления....................................................................................................... 487
Резюме................................................................................................................. 495
Заключение. Итоги и перспективы.......................................................................... 497
Приложение. Программное обеспечение................................................................. 498
Загрузка программного обеспечения.................................................................... 498
Использование среды IntelliJ IDEA........................................................................ 502

Вступление

О книге и не только
Не надо громких слов. Они потрясают воздух, но не собеседника.
из к/ф «Формула любви»
Вот уже многие годы язык Java входит в число самых популярных и востребованных. Он красивый, эффектный и, самое главное, очень производительный. Но,
к сожалению, не самый простой. Именно поэтому спрос на Java-программистов
неизменно высок. Язык Java — это бриллиант, который украсит багаж знаний любого программиста. А учить Java, как, я надеюсь, предстоит убедиться читателям
этой книги, не только полезно, но и интересно. В основу книги положены курсы
лекций, в разное время прочитанные мной для магистров физического факультета
Киевского национального университета им. Тараса Шевченко, бакалавров медико-инженерного факультета Национального технического университета Украины
«Киевский политехнический институт» и слушателей различных курсов по программированию. Материал книги и способ изложения адаптированы для всех, кто
желает изучать Java не только в учебных заведениях, но и самостоятельно. Поэтому
книга может использоваться и как самоучитель.

Объектно-ориентированное
программирование и Java
— На что жалуемся?
— На голову жалуется.
из к/ф «Формула любви»
Есть несколько концепций программирования, которые в той или иной степени
реализуются в разных языках программирования. Среди них особым образом
выделяется концепция объектно-ориентированного программирования (ООП),

10   Вступление
которая поддерживается всеми (или почти всеми) современными языками программирования. Концепция ООП — это реакция на значительное усложнение
программ и увеличение объема кода. ООП преимущественно используют при написании больших и сложных программ.



НА ЗАМЕТКУ
Программа считается большой, если она содержит несколько тысяч строк кода.
Понятно, что это очень условная оценка, которая, однако, позволяет составить
представление о том, что такое много и мало.

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



ПОДРОБНОСТИ
Концепция ООП базируется на трех фундаментальных принципах: инкапсуляции,
полиморфизме и наследовании.
Инкапсуляция подразумевает объединение в одно целое данных и кода для обработки этих данных. Обычно инкапсуляция реализуется через использование классов и объектов. В разных языках программирования все происходит по-разному.
Полиморфизм базируется на использовании универсальных интерфейсов для решения однотипных задач. Как мы узнаем далее, этот механизм в Java реализуется
за счет перегрузки и переопределения методов.
Наследование позволяет создавать новые классы на основе уже существующих
классов, что значительно экономит усилия, сокращает объем кода и повышает
его надежность.
Еще раз подчеркнем, что эти три принципа в той или иной степени присущи любому
языку программирования, поддерживающему парадигму ООП.
Наиболее популярными объектно-ориентированными языками программирования
сегодня принято считать, наряду с Java, языки C++ и С#. Исторически первым
появился язык C++, ставший существенно усовершенствованной версией C. Усовершенствования касались главным образом поддержки парадигмы ООП. Именно
С++ стал в известном смысле родительским для языков С# и Java. В этом несложно
убедиться, если сравнить синтаксисы языков — они очень схожи. Но если в языке C++ можно создавать программы как с использованием классов, так и без них,
то в языках Java и C# без ООП уже не обойтись.

Особенности языка Java    11

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



НА ЗАМЕТКУ
Что касается трудностей, то впадать в отчаяние не стоит: мы найдем способ обойти
все подводные камни и решим все проблемы.

Особенности языка Java
Русская речь не сложнее других. Вон Маргадон — дикий человек, и то выучил.
из к/ф «Формула любви»
Язык Java был разработан (с 1991 по 1995 год) инженерами компании Sun Micro­
systems, которую затем поглотила корпорация Oracle (www.oracle.com). Именно
Oracle теперь и отвечает за поддержку технологии Java.
Исторически стимулом к созданию Java (если точнее, то речь шла о разработке целой
технологии) стало желание получить программные средства для работы с бытовыми
приборами. Здесь на первый план выходит проблема универсальности программных
кодов. И так совпало, что как раз в это время начали бурно развиваться интернеттехнологии. Подход, использованный в Java, во многом идентичен подходу, примененному при разработке программ, предназначенных для работы во Всемирной
паутине. Именно это обстоятельство и способствовало быстрому росту популярности
Java (неформальный девиз Java звучит как «написано однажды — работает везде»).



НА ЗАМЕТКУ
Если вы создаете исходный код, заранее зная, на каком компьютере и с какой
операционной системой он будет выполняться, то у вас есть возможность оптимизировать программу под параметры исполнительной среды. Если же вы пишете
программу, предназначенную для использования в Интернете, то заранее не знаете
ни тип процессора, ни тип операционной системы, которые использует конечный
потребитель программного продукта. Особенностью интернет-среды является
принципиальное разнообразие используемых операционных систем и аппаратного
обеспечения. Отсюда — требование к универсальности кодов.

12   Вступление
Проблема универсальности программных кодов решена в Java в рамках концепции
виртуальной Java-машины (JVM, от Java Virtual Machine). Так, если обычно при
компиляции программы (например, написанной на C++) на выходе мы получаем
исполнительный машинный код, то в результате компиляции Java-программы получают промежуточный байт-код, который выполняется не операционной системой,
а виртуальной Java-машиной, представляющей собой специальную программу.
Разумеется, предварительно виртуальная Java-машина должна быть установлена
на компьютер пользователя. С одной стороны, это позволяет создавать достаточно
универсальные программы (в том смысле, что они могут использоваться с разными операционными системами). Но с другой стороны, платой за универсальность
является снижение скорости выполнения программ.
Кроме того, следует четко понимать, что язык Java создавался именно для написания
больших и сложных программ. Писать на Java консольные программы, которые выводят сообщения вроде “Hello, world!”, — это все равно что на крейсере отправиться
на ловлю карасей. Тем не менее Java позволяет решать и такие примитивные задачи.
К слову, большинство примеров в книге — простые программные коды, и в данном
случае это оправданно, поскольку в учебе хороши любые приемы — главное, чтобы
они были эффективными.

Java и другие языки программирования
Обо мне придумано столько небылиц, что
я устаю их опровергать.
из к/ф «Формула любви»
Несмотря на популярность, у языка Java есть конкуренты. Главные из них — языки
C++ и C#. Далее следует сказать несколько слов о том, как эти языки возникли
и развивались.



НА ЗАМЕТКУ
Кроме тройки лидеров (C++, C# и Java), есть и другие претенденты, которые
периодически оказываются на вершине (или очень близко к вершине) списка популярности языков. На сегодняшний день очень быстро набирают высоту такие
языки, как JavaScript и Python. Но у них немного иная концепция, и поэтому мы их
обсуждать не будем. А вот C++, C# и Java относятся к семейству языков, которые
берут свое начало от старого доброго C — одного из первых и самых удачных
языков программирования.

На заре программирования законодателем моды был язык С — язык для программистов-профессионалов. Благодаря простому и лаконичному синтаксису он
и сегодня имеет большую армию поклонников. Тем не менее время и технологии

Java и другие языки программирования    13

бросили вызов даже такому продуманному и эффективному языку, как С. Объем
программных кодов постоянно увеличивается. В какой-то момент стало понятно,
что для эффективного программирования необходимо менять базовые подходы. Так
на смену парадигме процедурного программирования пришла концепция ООП. Но
в исходной своей версии язык С не был рассчитан на поддержку ООП. В результате на свет появился язык С++ — расширение языка С для поддержки парадигмы
ООП. Затем был разработан язык Java, синтаксис которого внешне во многом напоминает синтаксис C++. Одновременно разработчики Java постарались учесть
и устранить недостатки С++ (а недостатки есть у любого языка). Поскольку Java
ориентирован на использование в Интернете, то упор был сделан на безопасность.
Универсальность и безопасность — вот два вектора, определившие развитие языка.
Язык C# разрабатывался компанией Microsoft после появления языка Java.
В каком-то смысле C# является ответом компании Microsoft на успех Java. В языке C# постарались учесть и исправить не только недоработки C++, но и изъяны
Java. Как и Java, C# является полностью объектно-ориентированным языком.
Как и в Java, при компиляции программ, написанных на C#, получают промежуточный код. Но между Java и C# есть и принципиальные отличия. Язык C#
является базовым для технологии .Net Framework. В рамках этой технологии код,
написанный на разных языках (не только C#), компилируется в промежуточный
код, а на уровне промежуточного кода объединяется в один проект. Хотя внешне
(и в плане синтаксиса, и на техническом уровне) языки похожи, идеологически
они совершенно разные.



НА ЗАМЕТКУ
То, что базовые конструкции в языках C++, C# и Java однотипны, — не случайно
и не удивительно. Дело в том, что при создании нового языка важно, чтобы он
стал популярным. Один из ключевых факторов, определяющих легкость перехода
на новый язык, — простота или узнаваемость синтаксиса. Поскольку язык C задал общий стандарт для языков программирования, то логично, что новые языки
тяготеют к тому, чтобы сохранить знакомые большому количеству программистов
синтаксические конструкции. И здесь важно понимать, что наличие таких сходств
совершенно не означает одинаковости языков. Каждый язык уникален и имеет
свои преимущества и недостатки.

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

14   Вступление
от C++ и C#, нет как таковых указателей. Скажем, в С++ имя массива является
указателем на его первый элемент. В Java (и в C#) доступ к массиву получают через переменную, которая ссылается на массив. Таким образом, в Java переменная
массива и сам массив — совсем не одно и то же. И хотя может показаться, что это
неудобно, на практике все выглядит иначе и данный подход имеет неоспоримые
преимущества.
Аналогичная ситуация имеет место и с объектами. Все объекты в Java и C# создаются динамически, а объектная переменная содержит ссылку на объект. При присваивании объектов ссылка с одного объекта перебрасывается на другой объект.
Это обстоятельство, как увидят читатели, имеет важные последствия.
В языке С++ основной (но не единственный) способ реализации текстовых значений связан с использованием символьных массивов. В Java для работы с текстом
есть несколько библиотечных классов, которые позволяют выполнять все текстовые
операции быстро, просто и надежно (нечто подобное реализовано и в C#). А вот
чего в Java нет, так это перегрузки операторов. И надо откровенно признать, что
это одно из упущений разработчиков языка.
В Java, как и в C#, нет множественного наследования: если в языке C++ у класса при
наследовании может быть несколько базовых классов, то в Java может наследоваться
только один класс. Вместо множественного наследования в Java используются интерфейсы. Причем с учетом нововведений в версии Java 8 (наличие в интерфейсах
кода по умолчанию для методов) потери сведены к минимуму.
Обобщенные типы в Java реализованы значительно скромнее по сравнению с C++
и даже C#. Зато в Java есть эффективная система поддержки многопоточного
программирования и обработки ошибок. К неоспоримым преимуществам языка
Java можно отнести и фундаментальную поддержку для разработки приложений
с графическим интерфейсом.
Java — красивый, надежный и эффективный язык со своими преимуществами и недостатками, с которыми нам предстоит познакомиться.

Программное обеспечение
От пальца не прикуривают, врать не буду.
А искры из глаз летят.
из к/ф «Формула любви»
В процессе изучения Java и работы над практическим материалом мы будем взаимодействовать с программным обеспечением (ПО), без которого обойтись крайне
сложно. Важно знать, какие именно программные средства нам нужны, где их можно
найти и как использовать.

Программное обеспечение    15

Недостатка в программных средствах для работы с Java нет. Есть много интересных
и полезных программных продуктов, большинство которых, кстати, распространяется на условиях лицензии с открытым кодом. Мы постараемся ограничиться
разумным минимумом.
Что же нам понадобится? Во-первых, код где-то нужно набирать. Поэтому пригодится редактор — программа, которая позволит создать файл с набором команд на
языке Java. Теоретически для этой цели сгодится и обычный текстовый редактор.
Но, как мы узнаем далее, есть средства и лучше. Во-вторых, программу предстоит
компилировать. Для этого понадобится специальная программа-компилятор. Такая программа создаст на основе файла с программой другой файл (или файлы)
с промежуточным байт-кодом. Затем данный байт-код должен выполняться на
компьютере. Это работа виртуальной машины. То есть нужна еще одна программа.
Без всех этих программ нам как будто не обойтись?
На практике необходимо установить систему JDK (сокращение от Java
Development Kit). Это набор средств разработки, в который входит, помимо
прочего, компилятор и среда выполнения JRE (сокращение от Java Runtime
Environment) — фактически та самая виртуальная машина. Загрузить систему
JDK можно на сайте компании Oracle www.oracle.com. Соответствующее ПО распространяется свободно. Обновления также можно загружать с сайта поддержки
языка Java www.java.com.



НА ЗАМЕТКУ
Как и где загружать ПО, а также методы работы с соответствующими программами описываются в приложении (в конце книги). Существует несколько
платформ Java. Нас интересует стандартная платформа Java Standard Edition
(сокращенно Java SE), рассчитанная на разработку обычных (не корпоративных)
приложений.

Можно было бы ограничиться установкой системы JDK, но тогда пришлось бы
набирать код в текстовом редакторе, а компилировать программы и запускать
их — в командной строке. Это не самый лучший вариант, поэтому используются
специальные программы, которые называются средами разработки (сокращенно
IDE, от Integrated Development Environment).
Среда разработки позволяет в простом и удобном режиме решать все задачи сразу,
не отвлекаясь на запуск разных вспомогательных программ, — набирать код, редактировать его, выполнять отладку, компиляцию и запускать скомпилированный
проект. Поэтому использование среды разработки — вполне разумный ход. При этом
для работы с Java существует много хороших и, что немаловажно, бесплатных сред
разработки с сопоставимой функциональностью. Во многом выбор той или иной
среды определяется личными предпочтениями и вкусами пользователя. На сегодня наиболее популярными средами разработки являются IntelliJ IDEA компании
JetBrains (www.jetbrains.com), NetBeans (сайт https://netbeans.org) и Eclipse (www.

16   Вступление
eclipse.org). Но есть и другие. Например, на сайте https://codenvy.io можно познако-

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



ПОДРОБНОСТИ
Обычно до установки среды разработки следует установить систему JDK. Подчерк­
нем: устанавливаемая версия среды разработки должна поддерживать установленную версию JDK. Дело в том, что обычно версии JDK обновляются быстрее,
чем версии сред разработки, поэтому не всегда та или иная среда разработки
поддерживает последнюю версию JDK.
На момент написания книги актуальной (последней) является версия Java 12.
Начиная с версии Java 9, поддерживаются только 64-разрядные операционные
системы. Критически важными являются обновления, появившиеся в версии
Java 8. Материал книги и представленные в книге примеры рассчитаны на то, что
обучающимися используется версия не ниже Java 8.
Примеры, представленные в книге, тестировались в среде разработки IntelliJ IDEA.

Особенности книги
Да, это от души. Замечательно. Достойно
восхищения.
из к/ф «Формула любви»
Книга имеет прикладную направленность и рассчитана на тех, кто изучает Java
самостоятельно или в рамках учебного курса в университете (институте или на
компьютерных курсах). Упор при подборе материала делался на то, чтобы даже
читатель —новичок в программировании мог с самого начала писать программы,
постепенно наращивая их сложность. Все программы, рассматриваемые в основной
части книги, можно разбить на две группы: учебные и повышенной сложности. В последнем случае речь обычно идет о вычислительных задачах. Читателям не следует
паниковать, если какие-то примеры вначале покажутся не очень понятными. Учебных
программ вполне достаточно, чтобы освоить и понять основные приемы в работе
с кодами. С обретением опыта и знаний можно вернуться к более сложным примерам.
Книга охватывает все основные концепции, необходимые для эффективного составления программ на Java. Вот некоторые из тем, которые рассматриваются в книге:
 Базовые типы и операторы.
 Управляющие инструкции (операторы цикла, условный оператор и оператор
выбора).

Полезные ресурсы    17

 Работа с массивами.
 Описание классов и создание объектов.
 Наследование и использование интерфейсов.
 Лямбда-выражения и работа со ссылками на методы.
 Обработка исключительных ситуаций.
 Многопоточное программирование.
 Обобщенные классы и методы.
 Система ввода/вывода и работа с файлами.
 Создание приложений с графическим интерфейсом.



НА ЗАМЕТКУ
Начиная с версии Java 11, апплеты больше не поддерживаются, поэтому в книге
они не обсуждаются.

В конце каждой главы приводится краткое резюме.

Полезные ресурсы
Огонь тоже считался божественным, пока
Прометей не выкрал его. Теперь мы кипятим
на нем воду.
из к/ф «Формула любви»
В книге представлен материал, необходимый для успешного освоения методов
и приемов работы с Java. Тем не менее всегда полезно получать информацию из
разных источников. Далее приводятся ссылки на ресурсы, которые могут быть
полезны в процессе изучения Java.
 Много полезных сведений и важной документации представлено на сайте компании Oracle www.oracle.com.
 Справку по среде разработки (той, которую читатель решит использовать)
можно получить на сайте поддержки соответствующей среды.
 Полезными могут быть многочисленные обучающие платформы, где можно
изучить программирование (для работы с некоторыми платформами нужно знать английский язык): Coursera (www.coursera.org), edX (www.edx.org),

18   Вступление
MIT Open Courseware (ресурс Массачусетского технологического института,
https://ocw.mit.edu).
 В интернете есть огромное количество видеоуроков, которые легко найти с помощью поисковых систем. Оптимальный вариант — ориентироваться на официальные учебные курсы, которые читаются студентам. Большинство ведущих
университетов выкладывают в свободный доступ записи лекций, в том числе
и по программированию на Java. Обычно такие курсы готовятся профессионалами и адаптированы для аудиторий с разным уровнем подготовки.
 Никакое учебное пособие не может заменить живое (или через онлайн) общение с людьми, поэтому с вопросами или идеями полезно обращаться на форумы программистов. Например, один из самых известных ресурсов Хабр
(https://habr.com) содержит много полезной информации разной направленности. Много информации можно найти на Stack Overflow (https://stackoverflow.
com); обратите внимание, что обсуждения ведутся на английском языке. Есть
и другие, которые читатель легко найдет в случае необходимости. Если возникают вопросы по поводу программных кодов и разных аспектов программирования, следует не лениться и не терять оптимизма, а искать. Какой бы ни
была проблема, скорее всего, кто-то уже сталкивался с подобным и с высокой
долей вероятности решение существует. Как говорится, кто ищет — тот всегда
найдет.

Обратная связь
Слово лечит, разговор мысль отгоняет.
из к/ф «Формула любви»
Полезную информацию читатели могут найти на моем сайте www.vasilev.kiev.ua.
Письма с пожеланиями и предложениями можно отправлять по адресу alex@vasilev.
kiev.ua. Хотя, к сожалению, у меня нет возможности (в силу очевидных причин)
ответить на все сообщения, это не приуменьшает благодарности читателям за их
отзывы и замечания.

От издательства    19

Благодарности
Не умеете лгать, молодой человек. Все люди
разделяются на тех, которым что-то надобно
от меня, и на остальных, от которых что-то
нужно мне.
из к/ф «Формула любви»
Моя огромная благодарность — читателям, которые проявляют интерес к книгам,
высказывают пожелания и замечания. Я искренне признателен своим студентам
и слушателям курсов, которые стали той благодарной и терпеливой аудиторией, на
которой апробировались и проверялись подходы и методы, положенные в основу
книги.

От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com
(издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.

1

Основы Java

Фандорин, у меня времени нет! Скажите
по-человечески. Я не понимаю этого языка.
из к/ф «Статский советник»
Язык Java является полностью объектно-ориентированным. Это означает, что для
составления даже самой простой программы необходимо описать класс.
Рассмотрение методов программирования в Java начнем с наиболее простых случаев. При этом нам все же придется использовать классы. Чтобы не загромождать
начало книги довольно отвлеченными и не всегда понятными для новичков вопросами по созданию классов и объектов, постулируем некоторые базовые синтаксические конструкции как основу создания программы в Java, а затем, когда у нас
уже будет небольшой опыт в программировании, обратимся к более подробному
рассмотрению методов объектно-ориентированного программирования (далее —
ООП). Такой подход позволит читателю, не знакомому с концепцией ООП, легче
и быстрее усваивать новый материал, а затем плавно перейти к созданию реальных
объектно-ориентированных программ в Java.

Простые программы
Отлично, отлично! Простенько и со вкусом!
из к/ф «Бриллиантовая рука»
Мы сразу начнем с небольшой программы, которая в процессе выполнения отображает сообщение в окне вывода среды разработки. Программа представлена
в листинге 1.1.

Простые программы    21
Листинг 1.1. Отображение сообщения в окне вывода
class Demo{
public static void main(String[] args){
System.out.println("Приступаем к изучению Java!");
}
}

После компиляции и запуска программы (например, в среде IntelliJ IDEA) в окне
вывода появляется сообщение:
Результат выполнения программы (из листинга 1.1)
Приступаем к изучению Java!

Рассмотрим код подробнее. Сразу отметим, что фигурными скобками отмечаются
блоки кода. Код размещается между открывающей (символ {) и закрывающей (символ }) фигурными скобками. В данном случае использовано две пары фигурных
скобок. Первая, внешняя, пара нужна для определения кода класса, вторая — для
определения метода этого класса.



НА ЗАМЕТКУ
Метод представляет собой именованный блок команд, которые выполняются при
вызове метода. Другими словами, есть набор команд, и этот набор команд имеет
имя.
Что такое класс, мы обсудим немного позже.

Создание программы в Java начинается с описания класса. Описание класса начинается с ключевого слова class. После этого следует уникальное имя класса.
Мы его придумываем сами. В данном случае класс называется Demo. Код класса
размещается в блоке из фигурных скобок.



ПОДРОБНОСТИ
Если мы назвали класс Demo, то файл, в котором описывается этот класс, должен
называться Demo.java. В противном случае программа может не скомпилироваться.

Для описания класса используют следующую синтаксическую конструкцию:
class название_класса{
// Описание класса
}

Код класса Demo состоит всего из одного метода с названием main() (здесь и далее
названия методов будут указываться с круглыми скобками после имени, чтобы

22   Глава 1. Основы Java
отличать их от названий переменных). Это главный метод программы. Называться
главный метод должен main() и никак иначе.



ПОДРОБНОСТИ
Каждая программа, написанная на Java, имеет один и только один главный метод. Этот метод обязательно называется main() и описывается по определенным
правилам с определенными атрибутами. Класс, в котором описан главный метод,
называется главным классом. Выполнение программы начинается с выполнения
кода главного метода. Поэтому команды, которые размещаются в теле главного
метода, — это именно те команды, которые выполняются в программе.

Главный метод описывается в соответствии с таким шаблоном:
public static void main(String[] args){
// Команды в теле главного метода
}

Помимо того что метод должен называться main(), в его описании (перед названием метода) указываются ключевые слова public, static и void. Ключевое слово
public означает, что метод является открытым и он доступен за пределами класса,
в котором описан.



ПОДРОБНОСТИ
Методы (и поля, о которых позже), описываемые в классе, могут иметь разный
уровень доступа. Уровень доступа определяется специальным ключевым словом
(public, private или protected) или его отсутствием. Уровень доступа, в свою
очередь, определяет, из какого места программы вы можете вызвать метод (или
обратиться к полю). Самый высокий уровень доступа — когда метод описан
с ключевым словом public. В таком случае доступ к методу есть практически
из любого места кода. Поскольку выполнение программы начинается с вызова
главного метода, то логично, что у него должен быть наивысший уровень доступа.

Ключевое слово static означает, что метод статический и для его вызова нет необходимости создавать объект класса.



ПОДРОБНОСТИ
Как отмечалось выше, метод — это именованный блок команд. Методы бывают
статические и обычные (нестатические). Статический метод, хотя он и описывается
в классе, существует сам по себе. Чтобы вызвать такой метод,достаточно знать,
в каком классе он описан. Нестатический метод спрятан в объекте. Чтобы вызвать
такой метод, сначала нужно создать объект. Объект создается на основе класса,
подобно тому как дом (аналог объекта) строится на основе генерального плана
(аналог класса). Если бы главный метод не был статическим, то для его вызова

Простые программы    23
на основе главного класса пришлось бы создать объект. Но чтобы создать объект, нужно запустить программу. А запуск программы — это выполнение главного
метода. Получается замкнутый круг. Чтобы его разорвать, главный метод должен
быть статическим.

Ключевое слово void означает, что метод не возвращает результат.



ПОДРОБНОСТИ
Методы могут возвращать результат. Если так, то после выполнения метода на
память остается некоторое значение (результат метода). Его можно использовать
в программе. Каждое значение относится к определенному типу (например, целое
число, символ, текст). Если метод возвращает результат, то в описании метода
указывается тип результата метода. Это специальный идентификатор, обозначающий определенный тип данных (например, int для целых чисел, char для
символов или String для текста — хотя в последнем случае не все так просто). Но
метод может и не возвращать результат. В таком случае при вызове метода просто
выполняются команды, которые есть в этом методе. Если метод не возвращает
результат, то идентификатором типа результата в описании метода указывается
ключевое слово void.
То, что главный метод не возвращает результат, вполне логично. Поскольку
главный метод — это фактически и есть программа, то возвращать результат
(в рассматриваемом случае) особо некуда.

Это — обязательные атрибуты метода main(). Они должны указываться всегда,
когда мы описываем главный метод. Но это еще не все. В круглых скобках после
имени главного метода указана инструкция String[] args. Она описывает аргумент
args главного метода. Аргументом является текстовый массив (набор значений
текстового типа).



ПОДРОБНОСТИ
Текстовые значения в Java реализуются как объекты класса String. Пока не вдаваясь в подробности и с некоторым упрощением можно рассматривать класс String
как текстовый тип данных. Массив, как мы узнаем немного позже, представляет
собой набор значений определенного типа. Чтобы показать, что мы имеем дело
с набором значений (массивом), а не с одним значением, к идентификатору типа
(в данном случае это String) добавляют пустые квадратные скобки []. В итоге
получается инструкция String[], обозначающая массив из текстовых значений.

Аргумент главного метода может понадобиться в случае, если при вызове программы ей передаются параметры. Тогда эти параметры считываются (в текстовом формате) и из них формируется массив. Ссылка на этот массив передается
в главный метод через аргумент. Если параметры программе не передаются (а они
обычно не передаются), то аргумент главного метода играет чисто декоративную

24   Глава 1. Основы Java
роль. Но описать его следует в любом случае. Поэтому инструкция String[] args
в описании главного метода тоже является обязательной.



НА ЗАМЕТКУ
Название аргумента главного метода (допустим, args) выбирает пользователь.
Но традиционно аргумент главного метода называют именно args.

Все это может поначалу выглядеть довольно запутанно. Но пугаться не стоит. Вот
главное, что нужно запомнить: каждый раз при создании новой программы мы
будем использовать определенный шаблон. Вот он:
class название_класса{
public static void main(String[] args){
// Команды в теле главного метода
}
}

Практически любая наша программа будет содержать этот шаблон. Команды, которые формируют собственно программу, размещаются в теле главного метода main().
Но вернемся к примеру (см. листинг 1.1). В теле главного метода — всего одна
команда System.out.println("Приступаем к изучению Java!"). Команда заканчивается точкой с запятой — это стандарт для Java (все команды заканчиваются точкой
с запятой). Командой с помощью встроенного метода println() в окне вывода
печатается сообщение "Приступаем к изучению Java!". Текст сообщения указан
аргументом метода.



ПОДРОБНОСТИ
Текстовые значения (текстовые литералы) в Java заключаются в двойные кавычки.

Команда вызова метода дает нам пример использования классического точечного
синтаксиса. Итак, есть библиотечный класс System. У этого класса есть статическое
поле out, которое связано с потоком вывода. Поле out является объектом. И у этого
объекта имеется метод println(), который нам нужно вызвать. В таком случае мы
указываем полную иерархию: класс, поле, метод. Разделителем является точка.
То есть инструкция вида System.out.println() означает, что нужно в классе System
найти объект out и вызвать из него метод println().



НА ЗАМЕТКУ
Важно понять: метод println() позволяет напечатать сообщение в окне вывода,
и вызывается он в формате System.out.println(). Остальное (в рассматриваемом
случае) не очень-то и важно.

Собственно, на этом анализ кода нашей первой программы мы заканчиваем.

Простые программы    25



НА ЗАМЕТКУ
Если у читателя возникли проблемы с компиляцией и запуском программы, можно
обратиться к Приложению, в котором кратко описаны методы работы со средой
разработки IntelliJ IDEA.

Далее мы рассмотрим еще одну простую программу (листинг 1.2), в которой тоже
выводится сообщение, но уже не в окно вывода, а в специальное диалоговое окно,
которое программой же и создается.
Листинг 1.2. Отображение сообщения в диалоговом окне
// Статический импорт метода:
import static javax.swing.JOptionPane.showMessageDialog;
class Demo{
public static void main(String[] args){
// Отображение сообщения в диалоговом окне:
showMessageDialog(null,"Программируем на Java!");
}
}

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

Рис. 1.1. Диалоговое окно с сообщением

Теперь постараемся разобраться, что происходит. Код программы — более чем
простой. В теле главного метода — всего одна команда showMessageDialog(null,
"Программируем на Java!"), посредством которой и отображается окно с сообщением. У метода — два аргумента, которые в команде вызова метода разделяются
запятыми. Второй аргумент "Программируем на Java!" — это сообщение, которое
появляется в диалоговом окне. А вот первым аргументом служит ключевое слово
null, обозначающее пустую ссылку (отсутствие значения). Вообще, первый аргумент определяет окно, которое является родительским для данного диалогового
окна. Инструкция null означает, что такого окна нет.



ПОДРОБНОСТИ
Есть такое понятие, как модальное окно. Допустим, имеется главное окно программы. Если появляется модальное окно, то пока вы его не закроете, доступ
к главному окну будет заблокирован. Обычно окно с сообщением используют
именно как модальное, которое при появлении должно заблокировать главное
окно программы (для диалогового окна это главное окно является родительским).

26   Глава 1. Основы Java
В нашем случае такого главного окна нет, поэтому ничего блокировать не нужно.
Как следствие, первым аргументом методу showMessageDialog() передаем ссылку
null. Практически каждый раз, когда мы будем использовать этот метод, первым
аргументом ему будет передаваться значение null.

Метод showMessageDialog() является статическим методом класса JOptionPane.
Чтобы класс стал доступен в программе, его необходимо импортировать. Мы
используем статический импорт, для чего в начале программы размещается инструкция import static javax.swing.JOptionPane.showMessageDialog. Она означает,
что в программу импортируется статический метод showMessageDialog. Благодаря
этому в программе метод можно использовать.



ПОДРОБНОСТИ
В Java все классы разбиваются по группам, которые называются пакетами. Когда
в программу импортируется класс (или его статические методы), то указывается полный путь к классу в иерархии пакетов. Так, выражение javax.swing.
JOptionPane.showMessageDialog в import-инструкции означает, что нас интересует метод showMessageDialog() из класса JOptionPane, который находится
в пакете swing, а этот пакет, в свою очередь, находится в пакете javax.
Программа может содержать несколько import-инструкций. Причем это может быть
обычный импорт или статический. Если импорт обычный, то после ключевого слова
import указывается класс (вместе с иерархией пакетов), который импортируется
в программу. В таком случае, если мы хотим использовать статический метод из
этого класса, то при вызове метода следует указывать и имя класса. Если импорт
статический, то после ключевого слова import указывается еще и ключевое слово static. В случае статического импорта при вызове статического метода имя
класса можно не указывать. То есть статический импорт, по сравнению с обычным
(нестатическим), удобнее. Недостаток статического импорта — в том, что он применим только к статическим полям и методам.
Классы (такие, например, как System), которые находятся в подпакете lang пакета
java, импортировать не нужно — они доступны по умолчанию.

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



ПОДРОБНОСТИ
В Java существует три типа комментариев:


Однострочный комментарий. Такой комментарий начинается с двойной косой
черты (символ //). Все, что находится в строке кода справа от двойной косой
черты, компилятором игнорируется.

Знакомство с переменными    27


Многострочный комментарий. Такой комментарий начинается последовательностью символов /* и заканчивается последовательностью символов */. Все,
что находится между символами /* и */, компилятором игнорируется.



Многострочный комментарий документирования. Начинается последовательностью символов /** и заканчивается последовательностью символов */.
Обычно используется в случае, если планируется автоматическое генерирование документации.

Знакомство с переменными
Это мелочи. Но нет ничего важнее мелочей!
из к/ф «Приключения Шерлока Холмса
и доктора Ватсона»
Переменная — это идентификатор (имя), с помощью которого можно получить доступ к памяти для записи значения или считывания значения. Переменную удобно
представлять в виде ячейки с названием (имя переменной), и в эту ячейку можно
что-то положить или посмотреть, что там находится. Данные, которые в принципе
можно хранить с помощью переменных, разбиты на типы: например, целые числа,
действительные числа, символы, логические значения. Каждая переменная предназначена для работы с данными только определенного типа. Соответственно,
у каждой переменной есть тип.
Чтобы использовать переменную в программе, ее необходимо объявить. При объявлении переменной указывается тип переменной и ее название. Тип определяется
с помощью специального идентификатора. Например, int означает целочисленный
тип, double — тип для чисел с плавающей точкой (действительные числа), char —
символьный тип (значением переменной может быть символ или буква). Для текста
мы будем использовать тип String.



ПОДРОБНОСТИ
Описанная выше схема, когда переменная содержит значение, относится к базовым, или примитивным, типам (таким, как int или char). Но есть еще и ссылочные
типы, переменные которых ссылаются на значение. Например, объектные переменные ссылаются на объект: значением такой переменной является адрес объекта в памяти. Текст реализуется как объект класса String и к базовым типам не
относится. Переменная класса String ссылается на текстовый объект. Особенности
работы с текстом мы еще будем обсуждать. Пока же, не вдаваясь в подробности,
будем использовать для работы с текстом тип String.

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

28   Глава 1. Основы Java
то их можно перечислить через запятую после идентификатора типа. Одновременно с объявлением переменной ей можно присвоить значение (инициализировать
переменную).



ПОДРОБНОСТИ
Если переменную объявить и инициализировать с ключевым словом final, то такая
переменная становится константой. Изменить значение константы в процессе
выполнения программы нельзя.



НА ЗАМЕТКУ
Область доступности переменных определяется блоком, в котором переменная
объявлена. Блок, в свою очередь, выделяется парой фигурных скобок { и }.

Далее мы рассмотрим программу, в которой используются переменные. В процессе
выполнения программы появляется диалоговое окно с полем ввода, в которое пользователь должен ввести текст. Текст считывается, появляется еще одно диалоговое
окно с информацией о введенном тексте, количестве символов в тексте, указаны
первая и последняя буквы в тексте. Обратимся к листингу 1.3.
Листинг 1.3. Знакомство с переменными
// Статический импорт:
import static javax.swing.JOptionPane.*;
class Demo{
public static void main(String[] args){
// Текстовые переменные:
String txt,str;
// Отображение окна с полем ввода:
txt=showInputDialog("Введите текст:");
// Целочисленная переменная:
int size=txt.length();
// Символьные переменные:
char A=txt.charAt(0);
char B=txt.charAt(size-1);
// Формируется значение текстовой переменной:
str="Текст: "+txt+"\n";
str+="Символов в тексте: "+size+"\n";
str+="Первый символ: "+A+"\n";
str+="Последний символ: "+B;
// Отображение диалогового окна:
showMessageDialog(null,str);
}
}

После запуска программы появляется окно (рис. 1.2).
В поле ввода окна мы набираем текст Изучаем Java и нажимаем кнопку OK. Окно
закроется, но появится новое (рис. 1.3).

Знакомство с переменными    29

Рис. 1.2. В окне с полем ввода указан
текст

Рис. 1.3. Диалоговое окно с информацией
о введенном тексте

Проанализируем код из примера. Мы используем статический импорт, причем
в инструкции import static javax.swing.JOptionPane.* вместо имени импортируемого метода указана звездочка * . В таком случае из класса JOptionPane
импортируются все статические методы. Нас интересуют два: уже знакомый нам
метод showMessageDialog() для отображения диалогового окна с сообщением
и новый для нас метод showInputDialog() для отображения диалогового окна
с полем ввода.
В главном методе объявляются две текстовые (тип String) переменные, txt и str.
Значение переменной txt вычисляется инструкцией txt=showInputDialog("Введите
текст:"). Здесь вызывается метод showInputDialog(), которым отображается окно
с полем ввода. Текст, переданный аргументом методу, появляется над полем ввода
в диалоговом окне. Метод возвращает результат. Это текст, который пользователь
ввел в поле ввода перед нажатием кнопки OK (см. рис. 1.2). Поскольку инструкция
вызова метода присваивается переменной txt, в результате значением переменной
становится тот текст, который ввел пользователь.



ПОДРОБНОСТИ
Оператором присваивания в Java является знак равенства =. Выражения вида
переменная=значение обрабатывается так: значение, указанное справа от оператора присваивания, присваивается переменной, указанной слева от оператора
присваивания.

Еще в программе объявляется целочисленная (тип int) переменная size. Значением
такой переменной может быть целое число. Ей сразу присваивается значение. В рассматриваемом случае значением присваивается выражение txt.length(), результат
которого — длина текста (количество символов), записанного в переменную txt.



ПОДРОБНОСТИ
Текстовая переменная txt является объектом. У текстовых объектов есть много
интересных методов, включая метод length(), который результатом возвращает
количество символов в текстовом объекте, из которого вызывается метод.

30   Глава 1. Основы Java
Метод charAt() позволяет прочитать символ из текста (в том объекте, из
которого вызывается метод). Аргументом методу передается индекс символа
(индексация символов начинается с нуля — то есть у первого символа в тексте
нулевой индекс).

Также мы используем две символьные (тип char) переменные, A и B. В переменную A
записывается первый символ из введенного пользователем текста (вычисляется
выражением txt.charAt(0)), а в переменную B записывается последняя буква
в тексте (вычисляется выражением txt.charAt(size-1)). В данном случае метод
charAt() вызывается из текстового объекта txt. Результатом метод возвращает
символ с указанным индексом.



ПОДРОБНОСТИ
Мы учли, что первый символ в тексте имеет нулевой индекс, а индекс последнего
элемента на единицу меньше длины текста.

Значение переменной str формируется несколькими командами. Начальное значение переменной дается выражением "Текст: "+txt+"\n", которым вычисляется
сумма (использован оператор сложения +) трех текстовых значений. Если складываются текстовые значения, то выполняется объединение текста.



ПОДРОБНОСТИ
Здесь и далее мы использовали инструкцию перехода к новой строке \n. Если текст
содержит такую инструкцию, то при попытке ее «напечатать» осуществляется
переход к новой строке.

Затем к текущему текстовому значению переменной str дописываются новые
блоки текста (команды str+="Символов в тексте: "+size+"\n", str+="Первый символ: "+A+"\n" и str+="Последний символ: "+B).



ПОДРОБНОСТИ
Обратите внимание. Во-первых, мы использовали оператор +=. Это один из составных операторов присваивания. Выражение вида X+=Y эквивалентно выражению X=X+Y: то есть к текущему значению переменной X добавляется значение Y.
Во-вторых, если к тексту добавляется число или символ, то это число или символ
автоматически преобразуются к текстовому формату и далее выполняется объединение текстовых строк.

После того как значение переменной str сформировано, showMessage­D ialog
(null,str) отображает диалоговое окно с сообщением.

Базовые типы данных    31

Базовые типы данных
Вы получите то, что желали, согласно
намеченным контурам.
из к/ф «Формула любви»
В Java существует четыре группы базовых типов: для работы с целыми числами
(четыре типа), для работы с действительными числами в формате с плавающей точкой (два типа), для использования символов (один тип) и логический тип (один).
Всего получается восемь базовых типов (табл. 1.1).
Таблица 1.1. Базовые (простые) типы в Java
Тип данных
(название)

Количество битов

Описание

Классоболочка

byte

8

Целые числа в диапазоне от –128 до 127

Byte

short

16

Целые числа в диапазоне от –32 768 до
32 767

Short

int

32

Целые числа в диапазоне от –2147483648 до
2147483647

Integer

long

64

Целые числа в диапазоне от –9223372036854775808 до
9223372036854775807

Long

float

32

Действительные числа. Минимальный
шаг дискретности (точность) составляет
величину 3,4 × 10–38, максимальное значение (по модулю) — 3,4 × 1038

Float

double

64

Действительные числа (двойной точности). Минимальный шаг дискретности (точность) составляет величину
1,7 × 10–308, максимальное значение (по
модулю) — 1,7 × 10308

Double

char

16

Тип для представления символьных значений. Реализуются символы с кодами от 0 до
65 536

Character

boolean

Зависит
от виртуальной
машины

Логический тип данных. Переменная этого
типа может принимать два значения: true
(истина) и false (ложь)

Boolean

32   Глава 1. Основы Java
В этой же таблице приведены названия классов-оболочек для базовых типов, используемых, когда переменную соответствующего типа необходимо реализовать как
объект. Далее изучим каждую группу базовых типов отдельно. В первую очередь
стоит обратить внимание на целочисленные типы данных.
 В Java существует четыре типа целочисленных данных: byte, short, int и long.
Отличаются типы количеством битов, выделяемых для записи значения соответствующего типа. Размер в битах увеличивается от 8 для типа byte до 64
для типа long (с шагом дискретности 8 бит). На практике, если нет крайней
необходимости, для работы с целыми числами рекомендуется использовать
тип int.
 Для работы с действительными числами используются типы float и double (на
практике обычно используется тип double). С помощью этих типов реализуется формат числа с плавающей точкой.
 В Java для символьных данных (тип char) выделяется 16 бит, что позволяет охватить практически все имеющиеся и использующиеся на сегодня символы.
 Что касается логического типа boolean, то переменные этого типа могут принимать всего два значения: true (истина) и false (ложь). Размер (в битах)
переменной типа boolean зависит от типа используемой виртуальной Javaмашины.



НА ЗАМЕТКУ
Есть такое понятие, как литерал, — это значение, предназначенное для восприятия человеком, которое не может быть изменено в программе. Текстовые
литералы (например, текст "Изучаем Java") заключаются в двойные кавычки.
Символьные литералы заключаются в одинарные кавычки (например, 'A' или
'Z'). Числовые литералы, кроме обычного десятичного представления (например, 123), могут быть записаны в восьмеричной и шестнадцатеричной системах
счисления. Восьмеричные литералы начинаются с нуля. Следующие цифры
в позиционной записи восьмеричного литерала могут принимать значения в диапазоне от 0 до 7 включительно. Например, восьмеричный литерал 012 означает
десятичное число 10. Шестнадцатеричные литералы начинаются с префикса 0x.
Для позиционного представления шестнадцатеричного числа используются
цифры от 0 до 9 и буквы от А до F. Например, шестнадцатеричный литерал 0x12
означает десятичное число 18.
Также можно использовать числа в формате с плавающей точкой (например,
12.3). Такие числа нередко представляют в научной (экспоненциальной) нотации,
в которой указывается мантисса и, через символ e или E, показатель степени.
Например, литерал 1.2E-3 соответствует числу 1,2 × 10–3, а литерал 2.5e7 соответствует числу 2,5 × 107.

Приведение типов    33

Приведение типов
— Узнаешь, Маргадон?
— Натюрлих, экселенц!
из к/ф «Формула любви»
Строгая типизация переменных вместе с очевидными преимуществами привносит
и ряд не столь очевидных проблем. Поясним это на простом примере. Предположим, что в программе объявлены две числовые переменные: одна типа int и другая
типа double. Переменным присвоены значения. Далее мы хотим к переменной типа
double прибавить значение переменной типа int и результат записать в первую
переменную. С формальной точки зрения здесь нет никакой проблемы, поскольку
целые числа являются подмножеством множества действительных чисел. С точки зрения программной логики ситуация не такая простая, ведь складываются
переменные разных типов. Понятно, что на самом деле проблемы не возникает
и описанную операцию можно выполнить. Выполнение операций подобного рода
базируется на автоматическом приведении типов. Другими словами, если нужно
вычислить выражение, в которое входят переменные разных типов, то автоматически выполняется преобразование входящих в выражение переменных к общему
формату. Процесс автоматического преобразования типов подчиняется нескольким
базовым правилам:
 Типы переменных, входящих в выражение, должны быть совместимыми. Например, целое число можно преобразовать в формат действительного числа,
чего не скажешь о текстовой строке.
 Целевой тип (тип, к которому выполняется приведение) должен быть шире
исходного типа. Другими словами, преобразование должно выполняться без
потери данных.
 Перед выполнением арифметических операций типы byte, short и char расширяются до типа int.
 Если в выражении есть операнды типа long, то расширение осуществляется до
типа long.
 Если в выражении есть операнды типа float, то расширение осуществляется до
типа float.
 Если в выражении есть операнды типа double, то расширение осуществляется
до типа double.
К этим правилам следует добавить не менее важные правила интерпретации литералов. Действительно, как следует рассматривать, например, число (литерал) 2?

34   Глава 1. Основы Java
Как значение типа int, типа long или, например, типа double? Ответы на подобные
вопросы дают следующие правила:
 Литералы, обозначающие целые числа, интерпретируются как значения
типа int.
 Литералы, обозначающие действительные числа, интерпретируются как значения типа double.
Хотя эти правила представляются логичными и простыми, нередко автоматическое приведение типов приводит к непредсказуемым, на первый взгляд, результатам и ошибкам. Например, представим, что объявляется несколько переменных
типа byte:
byte x=1,y=2,z;

Если мы теперь вычислим сумму x+y и захотим присвоить ее в качестве значения
переменной z, то возникнет ошибка. В чем причина? Хотя все три переменные
относятся к типу byte, при вычислении выражения x+y выполняется автоматическое преобразование к типу int. В результате имеет место попытка присвоить
значение типа int переменной типа byte . Поскольку в Java преобразования
с возможной потерей значений не допускаются, то и программа с таким кодом
не скомпилируется.



НА ЗАМЕТКУ
При этом если мы инициализируем переменную типа byte с помощью целочисленного литерала (который по умолчанию относится к типу int), то ошибки не
возникает (при условии, что присваиваемое переменной значение не выходит за
допустимый диапазон).

Или, например, мы объявляем переменную типа float, а затем пытаемся ей
присвоить значение, заданное числовым литералом (например, 2.5). И в этом
случае получим ошибку, поскольку литерал 2.5 относится к типу double, в то
время как переменная объявлена как относящаяся к типу float. Поскольку тип
double шире, чем тип float (диапазон возможных значений для типа double
больше, чем для типа float), то такая операция теоретически может привести
к потере значения. Хотя в данном случае потери значения и не произошло бы,
но операция все равно запрещена (поскольку она потенциально опасна) и возникает ошибка.
Для решения проблем подобного рода в Java предусмотрено явное приведение
типов. Правило простое: для приведения выражения к нужному типу перед этим
выражением указывается имя типа, заключенное в круглые скобки. Например,
следующий код является корректным:

Основные операторы    35

byte x=1,y=2,z;
// Использовано явное приведение типа:
z=(byte)(x+y);

Командой (byte)(x+y) вычисляется сумма значений переменных x и y, а результат
преобразуется к типу byte. Получается, что переменной типа byte присваивается
значение типа byte и проблем не возникает. Тем не менее следует понимать, что
явное приведение типа потенциально опасно, поскольку может приводить к потере
значения. Такие ситуации должен отслеживать программист — системой они не
отслеживаются.
Как отмечалось ранее, каждый литерал автоматически относится к определенному
типу. Но с помощью специальных суффиксов тип литерала можно изменить. Так,
суффикс L (или l) у целочисленного литерала (например, 123L) означает, что он
принадлежит к типу long, а суффикс F (или f) у литерала, обозначающего действительное число (например, 2.5F), означает, что этот литерал относится к типу float.
Поэтому мы можем, например, объявить переменную типа float, а затем присвоить
ей значение 2.5F. Ошибки в таком случае не будет.



ПОДРОБНОСТИ
В Java разрешена динамическая инициализация переменных, когда значением
переменной при объявлении присваивается выражение, содержащее другие переменные. Например:
int x=3,y=4;
int z=x*x+y*y;
В данном случае переменная z инициализируется выражением x*x+y*y, то есть
получает значение 25. При динамической инициализации все переменные, входящие в соответствующее выражение, должны быть предварительно объявлены
и им должны быть присвоены значения.

Основные операторы
Дядя Степан, помог бы ты им, а? Ну грех
смеяться над убогими.
из к/ф «Формула любви»
Все операторы Java можно разделить на четыре группы: арифметические, логические, побитовые и операторы сравнения. Рассмотрим последовательно каждую
группу операторов. Начнем с арифметических. Эти операторы перечислены
в табл. 1.2.

36   Глава 1. Основы Java
Таблица 1.2. Арифметические операторы Java
Оператор

Описание

+

Бинарный оператор сложения. Результатом команды вида a+b является
сумма значений переменных a и b

-

Бинарный оператор вычитания. Результатом команды вида a-b является разность значений переменных a и b

*

Бинарный оператор умножения. Результатом команды a*b является произведение значений переменных a и b

/

Бинарный оператор деления. Результатом команды вида a/b является
частное от деления значений переменных a и b. Для целочисленных
операндов по умолчанию выполняется деление нацело

%

Бинарный оператор вычисления остатка от деления. Результатом
команды вида a%b является остаток от целочисленного деления значений переменных a и b

++

Унарный оператор инкремента. В результате выполнения команды
вида a++ (или ++a) значение переменной a увеличивается на единицу

--

Унарный оператор декремента. В результате выполнения команды
вида a-- (или --a) значение переменной a уменьшается на единицу

Эти операторы имеют некоторые особенности. В первую очередь обращаем внимание на оператор деления /. Если операндами являются целые числа, то деление
выполняется нацело. Рассмотрим последовательность команд:
int a=7,b=2;
double x=a/b;

В данном примере переменная x получает значение 3.0, а не 3.5, как можно было бы
ожидать. Дело в том, что сначала вычисляется выражение a/b. Поскольку операнды
целочисленные, выполняется целочисленное деление (результат целочисленного
деления 7 на 2 равен 3). И только после этого полученное значение преобразуется
к формату double и присваивается переменной x.
Для того чтобы при целочисленных операндах выполнялось обычное (не целочисленное) деление, перед выражением с оператором деления указывается в круглых
скобках идентификатор типа double. Например, так:
int a=7,b=2;
double x=(double)a/b;

Теперь значение переменной x равно 3.5.

Основные операторы    37

В Java есть группа составных операторов присваивания. Если op — один из арифметических бинарных операторов, то соответствующий составной оператор присваивания выглядит как op =. Выражение вида x op =y является эквивалентом
команды x=x op y.



НА ЗАМЕТКУ
Речь об операторах +=, -=, *=, /= и %=. Например, выражение a+=b эквивалентно выражению a=a+b, выражение a*=b эквивалентно выражению a=a*b, и так
далее. Следует также отметить, что между командами вида x op=y и x=x op y
разница все же есть. На самом деле команда x op=y эквивалентна команде
x=(тип x)(x op y) — после вычисления выражения x op y оно еще и приводится к типу переменной x, после чего полученное значение присваивается
переменной x. Иногда это бывает важно. Например, если переменная x относится
к типу char и объявлена командой char x='A', то команда x+=1 вполне законна
и в результате переменная x будет иметь значение 'B'. Как это происходит?
К начальному значению 'A' переменной x прибавляется значение 1. В Java
есть автоматическое преобразование типа char в тип int. Если к символу прибавляется число, то символ автоматически преобразуется в число (результат
такого преобразования — код символа в кодовой таблице) и к этому числу прибавляется единица. То есть результатом выражения x+1 является целое число
(код буквы 'B'). А переменная x относится к типу char. Тип char в тип int
автоматически преобразуется, а тип int в тип char автоматически не преобразуется (но можно выполнить явное приведение типа). Поэтому переменной x
нельзя просто присвоить значение выражением x+1. Следует использовать
явное приведение типа как в команде x=(char)(x+1). Но если использована
команда x+=1, то после вычисления выражения x+1 оно насильно преобразуется
к типу char, и полученное символьное значение записывается в переменную x.
Число в символ преобразуется так: число интерпретируется как код символа
в кодовой таблице. Буквы в кодовой таблице расположены в соответствии с их
расположением в алфавите.

Еще два исключительно полезных унарных оператора — операторы инкремента (++) и декремента (--). Действие оператора декремента сводится к увеличению
на единицу значения операнда, а оператор декремента на единицу уменьшает
значение операнда. Другими словами, команда x++ эквивалентна команде x=x+1,
а команда x-- эквивалентна команде x=x-1.



НА ЗАМЕТКУ
Ситуация такая же, как с составными операторами присваивания. Команда вида
x++ или x-- эквивалентна соответственно командам x=(тип x)(x+1) и x=(тип x)
(x-1). То есть к текущему значению переменной x прибавляется единица (для
оператора инкремента) или вычитается единица (для оператора декремента),
и результат приводится к типу переменной x.

38   Глава 1. Основы Java
У операторов инкремента и декремента есть постфиксная форма (оператор следует
после операнда: x++ или x--) и префиксная форма (оператор располагается перед
операндом: ++x или --x). С точки зрения действия на операнд нет разницы в том,
префиксная или постфиксная форма оператора использована. Однако если инструкция с оператором инкремента или декремента является частью более сложного
выражения, то различие в префиксной и постфиксной форме операторов инкремента и декремента проявляется. Если использована префиксная форма оператора,
то значением выражения является новое значение операнда. Если использована
постфиксная форма оператора, то значением выражения является старое значение
операнда. Рассмотрим небольшой пример:
int n,m;
n=100;
m=n++;

В этом случае после выполнения команд переменная n будет иметь значение 101,
а переменная m — значение 100. При выполнении команды m=n++ переменная n
получает значение 101, а поскольку использована постфиксная форма оператора
инкремента, то значение выражения n++ равно 100. Такое значение получает переменная m.
Иной результат выполнения следующих команд:
int n,m;
n=100;
m=++n;

Обе переменные (n и m) в этом случае имеют значение 101. При выполнении команды m=++n на единицу увеличивается значение переменной n, а поскольку в команде
m=++n использована префиксная форма оператора инкремента, то значением выражения ++n является число 101.
Следующую группу образуют логические операторы (табл. 1.3). Операндами логических операторов являются переменные и литералы типа boolean.
Таблица 1.3. Логические операторы Java
Оператор

Описание

&

Бинарный оператор логическое и. Результатом операции вида A&B является значение true, если значения обоих операндов A и B равны true. В противном случае возвращается значение false

&&

Бинарный оператор логические и (сокращенная форма). Особенность
оператора, по сравнению с оператором &, состоит в том, что если значение
первого операнда равно false, то значение второго операнда не проверяется

Основные операторы    39

Оператор

Описание

|

Бинарный оператор логическое или. Результатом операции вида A|B является значение true, если значение хотя бы одного из операндов A и B равно
true. В противном случае возвращается значение false

||

Бинарный оператор логическое или (сокращенная форма). Особенность
оператора, по сравнению с оператором |, состоит в том, что если значение первого операнда равно true, то значение второго операнда не проверяется

^

Бинарный оператор исключающее или. Результатом операции вида A^B
является значение true, если значение одного и только одного операнда
А или B равно true. В противном случае возвращается значение false

!

Унарный оператор логическое отрицание. Результатом выражения вида !A
является значение true, если значение операнда A равно false. Если
значение операнда A равно true, то результатом выражения !A является
значение false

Логические операторы обычно используются в качестве условий в условных
операторах и операторах цикла. Все операторы сравнения — бинарные (табл. 1.4).
Таблица 1.4. Операторы сравнения Java
Оператор

Описание

==

Оператор равно. Результатом выражения вида A==B является значение
true, если операнды A и B имеют одинаковые значения. В противном
случае значением является false

<

Оператор не равно. Результатом выражения вида A=

Оператор больше или равно. Результатом выражения вида A>=B является
значение true, если значение операнда A не меньше значения операнда B.
В противном случае значением является false

!=

Оператор не равно. Результатом выражения вида A!=B является значение
true, если операнды A и B имеют разные значения. В противном случае
значением является false

40   Глава 1. Основы Java
Операторы сравнения обычно используются совместно с логическими операторами.
Для понимания принципов работы побитовых операторов (табл. 1.5) необходимо
иметь хотя бы элементарные познания о двоичном представлении чисел. Напомним
читателю некоторые основные моменты.
 В двоичном представлении позиционная запись числа содержит нули и единицы.
 Старший бит (самый первый слева) определяет знак числа. Для положительных чисел старший бит равен нулю, для отрицательных — единице.
Перевод из двоичной системы счисления положительного числа с позиционной
записью bn bn–1 ... b2 b1 b0, где параметры bk (k = 0, 1, ..., n) могут принимать значения 0
или 1, выполняется так: bn bn–1 ... b2 b1 b0 = b020 + b121 + b222 + ... + bn–1 2n–1 + bn2n .
Для перевода отрицательного двоичного числа в десятичное представление производится побитовое инвертирование кода (все нули меняются на единицы, а единицы
меняются на нули), полученное двоичное число переводится в десятичную систему,
к нему прибавляется единица и добавляется знак «минус».
Чтобы определить двоичный код для отрицательного числа (заданного в десятичной системе), модуль числа переводим в двоичный код, инвертируем этот код
и прибавляем единицу.
Таблица 1.5. Побитовые операторы Java
Оператор

Описание

&

Бинарный оператор побитовое и. Результатом выражения вида a&b
с целочисленными операндами a и b является целое число. Биты в этом
числе вычисляются сравнением соответствующих битов в представлении значений операндов a и b. Если каждый из двух сравниваемых битов
равен 1, то результатом (значение бита) является 1. В противном случае
соответствующий бит равен 0

|

Бинарный оператор побитовое или. Результатом выражения вида a|b
с целочисленными операндами a и b является целое число. Биты в этом
числе вычисляются сравнением соответствующих битов в представлении
значений операндов a и b. Если хотя бы один из двух сравниваемых битов
равен 1, то результатом (значение бита) является 1. В противном случае
результат (значение бита) равен 0

^

Бинарный оператор побитовое исключающее или. Результатом выражения
вида a^b с целочисленными операндами a и b является целое число. Биты
в числе-результате вычисляются сравнением соответствующих битов
в представлении значений операндов a и b. Если один и только один из
двух сравниваемых битов равен 1, то результатом (значением бита) является 1. В противном случае результат (значение бита) равен 0

Основные операторы    41

Оператор

Описание

~

Унарный оператор побитовая инверсия. Результатом выражения вида ~a
является целое число, бинарный код которого получается заменой в бинарном коде операнда a нулей на единицы и единиц на нули

>>

Бинарный оператор сдвиг вправо. Результатом выражения вида a>>n является число, получаемое сдвигом вправо в бинарном представлении первого операнда a на количество битов, определяемых вторым операндом n.
Исходное значение первого операнда при этом не меняется. Младшие
биты теряются, а старшие заполняются значением знакового бита



Бинарный оператор беззнаковый сдвиг вправо. Результатом выражения
вида a>>>n является число, получаемое сдвигом вправо в позиционном
представлении первого операнда a на количество битов, определяемых
вторым операндом n. Исходное значение первого операнда при этом не
меняется. Младшие биты теряются, а старшие заполняются нулями



НА ЗАМЕТКУ
Для бинарных побитовых операторов (как и для арифметических) существуют
составные операторы присваивания. Так, выражение вида a&=b является эквивалентом (с поправкой на приведение типа) команды a=a&b, выражение a^=b
эквивалентно команде a=a^b, и так далее.

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

Первым операндом указывается некоторое условие (выражение, возвращающее
логическое значение). Если условие истинно (значение true), тернарный оператор
результатом возвращает значение, указанное после вопросительного знака. Если
условие ложно (значение false), тернарный оператор результатом возвращает
значение после двоеточия.



ПОДРОБНОСТИ
Несколько замечаний по поводу оператора присваивания =. В Java оператор
присваивания возвращает значение. Команда вида x=y выполняется следующим
образом: вычисляется значение y и оно записывается в переменную x. Это же
значение является значением всего выражения x=y. Поэтому допустимой является,

42   Глава 1. Основы Java
например, команда вида x=y=z. В этом случае значение переменной z присваивается сначала переменной y, а затем значение выражения y=z (оно же значение
переменной y) присваивается переменной x.

В табл. 1.6 приведены данные о приоритете различных операторов в Java.
Таблица 1.6. Приоритеты операторов в Java
Приоритет

Операторы

1

Круглые скобки ( ), квадратные скобки [ ] и оператор «точка»

2

Инкремент ++, декремент --, побитовая инверсия ~ и логическое отрицание !

3

Умножение *, деление / и вычисление остатка %

4

Сложение + и вычитание -

5

Побитовые сдвиги >>, >>

6

Больше >, больше или равно >=, меньше или равно t?(S1+S2)/(T-t):-1;
System.out.println("Скорость на втором участке:");
// Результат:
System.out.println(
V2t?(S1+S2)/(T-t):-1. Тернарный оператор здесь необходим исключительно с одной целью: предотвратить возможное деление на ноль
при условии, что значения переменных T и t совпадают. Если общее время движения
превышает время движения по первому участку, значение скорости автомобиля на
втором участке вычисляется по приведенной выше формуле. Если данное условие
не выполняется, то переменной V2 для скорости на втором участке присваивается
формальное отрицательное значение -1 . В зависимости от значения перемен-

Использование основных операторов    47

ной V2 либо выводится информация о вычисленном значении скорости навтором
участке, либо появляется сообщение "Это невозможно!". Мы используем команду
System.out.println(V2=c*c.
Значение равно true, если уравнение имеет решения, и false — если не имеет.
Если значение переменной state равно true, то тернарным оператором в качестве
результата возвращается числовое значение asin(c/sqrt(a*a+b*b))-alpha, где
переменной alpha предварительно присвоено значение командой alpha=asin(a/
sqrt(a*a+b*b)). В этих выражениях использованы статические методы asin()
и sqrt() из класса Math для вычисления арксинуса и квадратного корня соответственно. Таким образом, при истинном условии значением возвращается решение
уравнения. Если условие (переменная state) равно false, то результатом возвращается текст "решений нет!".



НА ЗАМЕТКУ
При разных значениях условия тернарный оператор возвращает не просто разные
значения, а значения разного типа. Но проблем в данном случае не возникает, поскольку выражение на основе тернарного оператора передано аргументом методу
println(). В этом случае результат тернарного оператора, каким бы он ни был,
автоматически преобразуется в текстовый формат.

54   Глава 1. Основы Java
Результат выполнения программы будет таким:
Результат выполнения программы (из листинга 1.9)
Уравнение a*cos(x)+b*sin(x)=c
Параметры:
a=5.0
b=3.0
c=1.0
Решение для x: -0.8580262366249893

Если поменять значения исходных параметров уравнения (переменной c присвоить
значение 10), получим следующее:
Результат выполнения программы (из листинга 1.9)
Уравнение a*cos(x)+b*sin(x)=c
Параметры:
a=5.0
b=3.0
c=10.0
Решение для x: решений нет!

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

Кодирование символов
Рассмотрим простую иллюстративную программу, в которой для записи сразу двух
символьных значений типа char используется одна переменная целочисленного
типа int.
В программе учитывается то обстоятельство, что тип int в Java имеет размер 32 бита,
а для записи основных символов достаточно 16 бит. Таким образом, объем памяти,
выделяемой переменной типа int, достаточен для записи по меньшей мере двух
символов (значений типа char). Принцип записи символьных значений в виде
числа следующий: начальные 16 битов числа (младшие биты) будут содержать
код первого символа, а следующие 16 битов числа (старшие биты) — код второго
символа (листинг 1.10).
Листинг 1.10. Кодирование символов
class Demo{
public static void main(String args[]){
// Кодовое число:
int num;
// Исходные буквы для кодирования:
char A='А',B='ы';
// Буквы после декодирования:

Использование основных операторов    55

}

}

char X,Y;
// Вычисление кода:
num=((int)B>16);
X=(char)(num^((int)Y