- •Содержание
- •Глава 1. Общие представления о языке Java 6
- •Глава 2. Объектно-ориентированное проектирование и платформа NetBeans 26
- •Глава 3. Примитивные типы данных и операторы для работы с ними 78
- •Глава 4. Работа с числами в языке Java 95
- •Глава 5. Управляющие конструкции 112
- •Глава 6. Начальные сведения об объектном программировании 128
- •Глава 7. Важнейшие объектные типы 175
- •Введение
- •Глава 1. Общие представления о языке Java
- •1.1. Java и другие языки программирования. Системное и прикладное программирование
- •1.2. Виртуальная Java-машина, байт-код, jit-компиляция. Категории программ, написанных на языке Java
- •1.3.Алфавит языка Java. Десятичные и шестнадцатеричные цифры и целые числа. Зарезервированные слова Алфавит языка Java
- •Десятичные и шестнадцатеричные цифры и целые числа
- •Зарезервированные слова языка Java
- •1.4. Управляющие последовательности. Символы Unicode. Специальные символы Управляющие последовательности
- •Простые специальные символы
- •Составные специальные символы
- •1.5.Идентификаторы. Переменные и типы. Примитивные и ссылочные типы
- •Краткие итоги по главе 1
- •Задания
- •Глава 2. Объектно-ориентированное проектирование и платформа NetBeans
- •2.1.Процедурное и объектно-ориентированное программирование. Инкапсуляция
- •2.2. Работа со ссылочными переменными. Сборка мусора
- •2.3. Проекты NetBeans. Пакеты. Уровни видимости классов. Импорт классов
- •2.4. Базовые пакеты и классы Java
- •2.5. Создание в NetBeans простейшего приложения Java
- •2.6. Компиляция файлов проекта и запуск приложения
- •2.7. Структура проекта NetBeans
- •2.8. Создание в NetBeans приложения Java с графическим интерфейсом
- •2.9. Редактор экранных форм
- •2.10. Внешний вид приложения
- •2.11. Ведение проектов
- •2.11. Редактирование меню экранной формы
- •2.12. Создание нового класса
- •2.13. Документирование исходного кода в Java
- •2.14. Основные компоненты пакетов swing и awt
- •2.15. Технологии Java и .Net
- •Краткие итоги по главе 2
- •Задания
- •Глава 3. Примитивные типы данных и операторы для работы с ними
- •3.1.Булевский (логический) тип
- •3.2.Целые типы, переменные, константы
- •3.3.Основные операторы для работы с целочисленными величинами
- •3.4.Вещественные типы и класс Math
- •3.5.Правила явного и автоматического преобразования типа при работе с числовыми величинами
- •3.6. Оболочечные классы. Упаковка (boxing) и распаковка (unboxing)
- •3.7.Приоритет операторов
- •3.8.Типы-перечисления (enum)
- •Краткие итоги по главе 3
- •Задания
- •Глава 4. Работа с числами в языке Java
- •4.1 Двоичное представление целых чисел Позиционные и непозиционные системы счисления
- •Двоичное представление положительных целых чисел
- •Двоичное представление отрицательных целых чисел. Дополнительный код
- •Проблемы целочисленной машинной арифметики
- •Шестнадцатеричное представление целых чисел и перевод из одной системы счисления в другую
- •4.2. Побитовые маски и сдвиги
- •4.3. Двоичное представление вещественных чисел Двоичные дроби
- •Мантисса и порядок числа
- •Стандарт ieee 754 представления чисел в формате с плавающей точкой*
- •Краткие итоги по главе 4
- •Задания
- •Глава 5. Управляющие конструкции Составной оператор
- •Условный оператор if
- •Оператор выбора switch
- •Условное выражение …?... : …
- •Оператор цикла for
- •Оператор цикла while – цикл с предусловием
- •Оператор цикла do...While – цикл с постусловием
- •Операторы прерывания continue, break, return, System.Exit
- •Краткие итоги по главе 5
- •Задания
- •Глава 6. Начальные сведения об объектном программировании
- •Наследование и полиморфизм. Uml-диаграммы
- •Функции. Модификаторы. Передача примитивных типов в функции
- •Локальные и глобальные переменные. Модификаторы доступа и правила видимости. Ссылка this
- •Передача ссылочных типов в функции. Проблема изменения ссылки внутри подпрограммы
- •Наследование. Суперклассы и подклассы. Переопределение методов
- •Наследование и правила видимости. Зарезервированное слово super
- •Статическое и динамическое связывание методов. Полиморфизм
- •Базовый класс Object
- •Конструкторы. Зарезервированные слова super и this. Блоки инициализации
- •Удаление неиспользуемых объектов и метод finalize. Проблема деструкторов для сложно устроенных объектов
- •Перегрузка методов
- •Правила совместимости ссылочных типов как основа использования полиморфного кода. Приведение и проверка типов
- •Рефакторинг
- •Reverse engineering – построение uml-диаграмм по разработанным классам
- •Краткие итоги по главе 6
- •Задания
- •Глава 7. Важнейшие объектные типы Массивы
- •Коллекции, списки, итераторы
- •Работа со строками в Java. Строки как объекты. Классы String, StringBuffer и StringBuilder
- •Работа с графикой
- •Исключительные ситуации Обработка исключительных ситуаций
- •Иерархия исключительных ситуаций
- •Объявление типа исключительной ситуации и оператор throw
- •Объявление метода, который может возбуждать исключительную ситуацию. Зарезервированное слово throws
- •Работа с файлами и папками
- •Краткие итоги по главе 7
- •Задания
- •Глава 8. Наследование: проблемы и альтернативы. Интерфейсы. Композиция Проблемы множественного наследования классов. Интерфейсы
- •Отличия интерфейсов от классов. Проблемы наследования интерфейсов
- •Пример на использование интерфейсов
- •Композиция как альтернатива множественному наследованию
- •Краткие итоги по главе 8
- •Задания
- •Глава 9. Дополнительные элементы объектного программирования на языке Java Потоки выполнения (threads) и синхронизация
- •Преимущества и проблемы при работе с потоками выполнения
- •Синхронизация по ресурсам и событиям
- •Класс Thread и интерфейс Runnable. Создание и запуск потока выполнения
- •Поля и методы, заданные в классе Thread
- •Подключение внешних библиотек dll.“Родные” (native) методы*
- •Краткие итоги по главе 9
- •Задания
- •Глава 10. Введение в сетевое программирование Краткая справка по языку html
- •Апплеты
- •Сервлеты
- •Технология jsp – Java Server Pages
- •Краткие итоги по главе 10
- •Задания
- •Глава 11. Встроенные классы Виды встроенных классов
- •Вложенные (nested) классы и интерфейсы
- •Внутренние (inner) классы
- •Локальные (local) классы
- •Анонимные (anonimous) классы и обработчики событий
- •Анонимные (anonimous) классы и слушатели событий (listeners)
- •Краткие итоги по главе 11
- •Задания
- •Глава 12. Компонентное программирование Компонентная архитектура JavaBeans
- •Мастер создания компонента в NetBeans
- •Пример создания компонента в NetBeans – панель с заголовком
- •Добавление в компонент новых свойств
- •Добавление в компонент новых событий
- •Краткие итоги по главе 12
- •Задания
- •Литература
- •Дополнительная литература
- •276 Курс подготовлен при поддержке Sun Microsystems
4.2. Побитовые маски и сдвиги
Оператор |
Название |
Пример |
Примечание |
~ |
Оператор побитового дополнения (побитовое “не”, побитовое отрицание) |
~i |
|
^ |
Оператор “ побитовое исключающее или” (XOR) |
i^j |
|
& |
Оператор “побитовое и” (AND) |
i&j |
|
| |
Оператор “побитовое или” (OR) |
i|j |
|
<< |
Оператор левого побитового сдвига |
>>> |
Оператор беззнакового правого побитового сдвига |
>> |
Оператор правого побитового сдвига с сохранением знака отрицательного числа |
&= |
y&=x эквивалентно y=y&x |
|= |
y|=x эквивалентно y=y|x |
^= |
y^=x эквивалентно y=y^x |
>>= |
y>>=x эквивалентно y= y>>x |
>>>= |
y>>>=x эквивалентно y= y>>>x |
<<= |
y<<=x эквивалентно y= y<<x |
Побитовые операции – когда целые числа рассматриваются как наборы бит, где 0 и 1 играют роли логического нуля и логической единицы. При этом все логические операции для двух чисел осуществляются поразрядно – k-тый разряд первого числа с k-тым разрядом второго. Для простоты мы будем рассматривать четырёхбитовые ячейки, хотя реально самая малая по размеру ячейка восьмибитовая и соответствует типу byte.
а) установка в числе a нужных бит в 1 с помощью маски m операцией a|m (арифметический, или, что то же, побитовый оператор OR).
Пусть число a = a3*23 + a2*22 + a1*21 + a0*20 , где значения ai – содержание соответствующих бит числа (то есть либо нули , либо единицы).
a |
a3 |
a2 |
a1 |
a0 |
m |
0 |
1 |
0 |
1 |
a|m |
a3 |
1 |
a1 |
1 |
Видно, что независимо от начального значения в числе a в результате нулевой и второй бит установились в единицу. Таким образом, операцию OR с маской можно использовать для установки нужных бит переменной в единицу, если нужные биты маски установлены в единицу, а остальные – нули.
б) установка в числе a нужных бит в 0 с помощью маски m операцией a&m (арифметический, или, что то же, побитовый оператор AND):
a |
a3 |
a2 |
a1 |
a0 |
m |
0 |
1 |
0 |
1 |
a&m |
0 |
a2 |
0 |
a0 |
Видно, что независимо от начального значения в числе a в результате первый и третий бит установились в нуль. Таким образом, операцию AND с маской можно использовать для установки нужных бит переменной в ноль, если нужные биты маски установлены в ноль, а остальные – единицы.
в) инверсия (замена единиц на нули, а нулей на единицы) в битах числа a , стоящих на задаваемых маской m местах, операцией a^m (арифметический, или, что то же, побитовый оператор XOR):
a |
1 |
1 |
0 |
0 |
m |
0 |
1 |
0 |
1 |
a^m |
1 |
0 |
0 |
1 |
Видно, что если в бите, где маска m имеет единицу, у числа a происходит инверсия: если стоит 1, в результате будет 0, а если 0 – в результате будет 1. В остальных битах значение не меняется.
Восстановление первоначального значения после операции XOR – повторное XOR с той же битовой маской:
a^m |
1 |
0 |
0 |
1 |
m |
0 |
1 |
0 |
1 |
(a^m)^m |
1 |
1 |
0 |
0 |
Видно, что содержание ячейки приняло то же значение, что было первоначально в ячейке a. Очевидно, что всегда (a ^ m) ^ m = a, так как повторная инверсия возвращает первоначальные значения в битах числа. Операция XOR часто используется в программировании для инверсии цветов частей экрана с сохранением в памяти только информации о маске. Повторное XOR с той же маской восстанавливает первоначальное изображение. - Имеется команда перевода вывода графики в режим XOR при рисовании, для этого используется команда graphics.setXORMode(цвет).
Ещё одна область, где часто используется эта операция – криптография.
Инверсия всех битов числа осуществляется с помощью побитового отрицания ~a.
Побитовые сдвиги “<<”, “>>” и “>>>” приводят к перемещению всех бит ячейки, к которой применяется оператор, на указанное число бит влево или вправо. Сначала рассмотрим действие операторов на положительные целые числа.
Побитовый сдвиг на n бит влево m<<n эквивалентен быстрому целочисленному умножению числа m на 2n. Младшие биты (находящиеся справа), освобождающиеся после сдвигов, заполняются нулями. Следует учитывать, что старшие биты (находящиеся слева), выходящие за пределы ячейки, теряются, как и при обычном целочисленном переполнении.
Побитовые сдвиги на n бит вправо m>>n или m>>>n эквивалентны быстрому целочисленному делению числа m на 2n. При этом для положительных m разницы между операторами “>>” и “>>>” нет.
Рассмотрим теперь операции побитовых сдвигов для отрицательных чисел m. Поскольку они хранятся в дополнительном коде, их действие нетривиально. Как и раньше, для простоты будем считать, что ячейки четырёхбитовые, хотя на деле побитовые операции проводятся только для ячеек типа int или long, то есть для 32-битных или 64-битных чисел.
Пусть m равно -1. В этом случае m=11112. Оператор m<<1 даст m=111102, но из-за четырёхбитности ячейки старший бит теряется, и мы получаем m=11102=-2. То есть также получается полная эквивалентность умножению m на 2n.
Иная ситуация возникает при побитовых сдвигах вправо. Оператор правого сдвига “>>” для положительных чисел заполняет освободившиеся биты нулями, а для отрицательных – единицами. Легко заметить, что этот оператор эквивалентен быстрому целочисленному делению числа m на 2n как для положительных, так и для отрицательных чисел. Оператор m>>>n, заполняющий нулями освободившиеся после сдвигов биты, переводит отрицательные числа в положительные. Поэтому он не может быть эквивалентен быстрому делению числа на 2n. Но иногда такой оператор бывает нужен для манипуляции с наборами бит, хранящихся в числовой ячейке. Само значение числа в этом случае значения не имеет, а ячейка используется как буфер соответствующего размера.
Например, можно преобразовать последовательность бит, образующее некое целое значение, в число типа float методом Float.intBitsToFloat(целое значение) или типа double методом Double.intBitsToDouble (целое значение). Так, Float.intBitsToFloat(0x7F7FFFFF) даст максимальное значение типа float.