- •Что такое Java?
- •История создания Java
- •Сложности внутри Sun Microsystems
- •Проект Green
- •Компания FirstPerson
- •Возрождение OaK
- •Java выходит в свет
- •История развития Java
- •Браузеры
- •Сетевые компьютеры
- •Платформа Java
- •Основные версии и продукты Java
- •Заключение
- •Методология процедурно-ориентированного программирования
- •Методология объектно-ориентированного программирования
- •Объекты
- •Состояние
- •Поведение
- •Уникальность
- •Инкапсуляция
- •Наследование
- •Полиморфизм
- •Типы отношений между классами
- •Агрегация
- •Ассоциация
- •Наследование
- •Метаклассы
- •Достоинства ооп
- •Недостатки ооп
- •Заключение
- •Кодировка
- •Анализ программы
- •Пробелы
- •Комментарии
- •Лексемы
- •Виды лексем
- •Идентификаторы
- •Ключевые слова
- •Литералы
- •Целочисленные литералы
- •Дробные литералы
- •Логические литералы
- •Символьные литералы
- •Строковые литералы
- •Null-литерал
- •Разделители
- •Операторы
- •Пример программы
- •Дополнение. Работа с операторами
- •Операторы присваивания и сравнения
- •Арифметические операции
- •Логические операторы
- •Битовые операции
- •Заключение
- •Введение
- •Имена Простые и составные имена. Элементы
- •Имена и идентификаторы
- •Область видимости (введение)
- •Элементы пакета
- •Платформенная поддержка пакетов
- •Модуль компиляции
- •Объявление пакета
- •Импорт-выражения
- •Объявление верхнего уровня
- •Уникальность имен пакетов
- •Область видимости имен
- •"Затеняющее" объявление (Shadowing)
- •"Заслоняющее" объявление (Obscuring)
- •Соглашения по именованию
- •Заключение
- •Введение
- •Модификаторы доступа
- •Предназначение модификаторов доступа
- •Разграничение доступа в Java
- •Объявление классов
- •Заголовок класса
- •Тело класса
- •Объявление полей
- •Объявление методов
- •Объявление конструкторов
- •Инициализаторы
- •Дополнительные свойства классов
- •Метод main
- •Параметры методов
- •Перегруженные методы
- •Заключение
- •Введение
- •Виды приведений
- •Тождественное преобразование
- •Преобразование примитивных типов (расширение и сужение)
- •Преобразование ссылочных типов (расширение и сужение)
- •Преобразование к строке
- •Запрещенные преобразования
- •Применение приведений
- •Присвоение значений
- •Вызов метода
- •Явное приведение
- •Оператор конкатенации строк
- •Числовое расширение
- •Унарное числовое расширение
- •Бинарное числовое расширение
- •Тип переменной и тип ее значения
- •Заключение
- •Статические элементы
- •Ключевые слова this и super
- •Ключевое слово abstract
- •Интерфейсы
- •Объявление интерфейсов
- •Реализация интерфейса
- •Применение интерфейсов
- •Полиморфизм
- •Полиморфизм и объекты
- •Заключение
- •Массивы как тип данных в Java
- •Объявление массивов
- •Инициализация массивов
- •Многомерные массивы
- •Класс массива
- •Преобразование типов для массивов
- •Ошибка ArrayStoreException
- •Переменные типа массив и их значения
- •Клонирование
- •Клонирование массивов
- •Заключение
- •Управление ходом программы
- •Нормальное и прерванное выполнение операторов
- •Блоки и локальные переменные
- •Пустой оператор
- •Оператор if
- •Оператор switch
- •Управление циклами
- •Цикл while
- •Цикл do
- •Цикл for
- •Операторы break и continue
- •Оператор continue
- •Оператор break
- •Именованные блоки
- •Оператор return
- •Оператор synchronized
- •Ошибки при работе программы. Исключения (Exceptions)
- •Причины возникновения ошибок
- •Обработка исключительных ситуаций Конструкция try-catch
- •Конструкция try-catch-finally
- •Использование оператора throw
- •Проверяемые и непроверяемые исключения
- •Создание пользовательских классов исключений
- •Переопределение методов и исключения
- •Особые случаи
- •Заключение
- •Введение
- •Дерево компонентов
- •Положение
- •Видимость
- •Доступность
- •Алгоритм отрисовки
- •Методы класса Graphics для отрисовки
- •Состояние Graphics
- •Clip (ограничитель)
- •Методы repaint и update
- •Прорисовка контейнера
- •Наследники класса Component
- •Класс Canvas
- •Класс Label
- •Класс Button
- •Классы Checkbox и CheckboxGroup
- •Классы Choice и List
- •Классы TextComponent, TextField, TextArea
- •Класс Scrollbar
- •Наследники Container
- •Класс Panel
- •Класс ScrollPane
- •Класс Window
- •Классы Frame и Dialog
- •Класс FileDialog
- •Обработка пользовательских событий
- •Событие ActionEvent
- •События awt
- •Обработка событий с помощью внутренних классов
- •Пример приложения, использующего модель событий
- •Апплеты
- •Жизненный цикл апплета
- •Передача параметров
- •Интерфейс AppletContext
- •Менеджеры компоновки
- •Класс FlowLayout
- •Класс BorderLayout
- •Класс GridLayout
- •Класс CardLayout
- •Заключение
- •Введение
- •Многопоточная архитектура
- •Базовые классы для работы с потоками Класс Thread
- •Интерфейс Runnable
- •Работа с приоритетами
- •Демон-потоки
- •Синхронизация
- •Хранение переменных в памяти
- •Модификатор volatile
- •Блокировки
- •Методы wait(), notify(), notifyAll() класса Object
- •Заключение
- •Введение
- •Классы-обертки
- •Системные классы
- •SecurityManager – менеджер безопасности
- •Потоки исполнения
- •Исключения
- •Заключение
- •Работа с датами и временем Класс Date
- •Классы Calendar и GregorianCalendar
- •Метод set(int field,int value).
- •Метод add(int field,int delta).
- •Метод roll(int field,int delta).
- •Класс TimeZone
- •Класс SimpleTimeZone
- •Интерфейс Observer и класс Observable
- •Коллекции
- •Интерфейсы Интерфейс Collection
- •Интерфейс Set
- •Интерфейс List
- •Интерфейс Map
- •Интерфейс SortedSet
- •Интерфейс SortedMap
- •Интерфейс Iterator
- •Aбстрактные классы, используемые при работе с коллекциями
- •Конкретные классы коллекций
- •Класс Collections
- •Класс Properties
- •Интерфейс Comparator
- •Класс Arrays
- •Класс StringTokenizer
- •Класс BitSet
- •Класс Random
- •Локализация Класс Locale
- •Класс ResourceBundle
- •Классы ListResourceBundle и PropertiesResourceBundle
- •Заключение
- •Система ввода/вывода. Потоки данных (stream)
- •Классы InputStream и OutputStream
- •Классы-реализации потоков данных Классы ByteArrayInputStream и ByteArrayOutputStream
- •Классы FileInputStream и FileOutputStream
- •Классы FilterInputStream и FilterOutputStream и их наследники
- •Сериализация объектов (serialization)
- •Стандартная сериализация
- •Восстановление состояния
- •Граф сериализации
- •Расширение стандартной сериализации
- •Классы Reader и Writer и их наследники
- •Класс StreamTokenizer
- •Работа с файловой системой Класс File
- •Класс RandomAccessFile
- •Заключение
- •Основы модели osi
- •Класс a
- •Класс b
- •Класс c
- •Подсети. Маска подсети
- •Протоколы arp, rarp
- •Утилиты для работы с сетью
- •Пакет java.Net
- •Заключение
"Затеняющее" объявление (Shadowing)
Самыми распространенными случаями возникновения конфликта имен является выражение, импортирующее пакет, и объявление локальных переменных, или параметров методов, конструкторов, обработчиков ошибок. Импорт пакета подробно рассматривался в этой главе. Если импортированный и текущий пакеты содержат одноименные типы, то их области пересекаются. Как уже говорилось, предпочтение отдается типу из текущего пакета. Также рассказывалось о том, как эту проблему решать.
Перейдем к проблеме перекрытия имен полей класса и локальных переменных. Пример:
class Human {
int age;
// возраст
int getAge() {
return age;
}
void setAge(int age) {
age=age; // ???
}
}
В классе Human (человек) объявлено поле age (возраст). Удобно определить также метод setAge(), который должен устанавливать новое значение возраста для человека. Вполне логично сделать у метода setAge() один входной аргумент, который также будет называться age (ведь в качестве этого аргумента будет передаваться новое значение возраста). Получается, что в реализации метода setAge() нужно написать age=age, в первом случае подразумевая поле класса, во втором - параметр метода. Понятно, что хотя с точки зрения компилятора это корректная конструкция, попытка сослаться на две разные переменные через одно имя успехом не увенчается. Надо заметить, что такие ошибки случаются порой даже у опытных разработчиков.
Во-первых, рассмотрим, из-за чего возникла конфликтная ситуация. Есть два элемента языка – аргумент метода и поле класса, области видимости которых пересеклись. Область видимости поля класса больше, она охватывает все тело класса, в то время как область видимости аргумента метода включает только сам метод. В таком случае внутри области пересечения по простому имени доступен именно аргумент метода, а поле класса "затеняется" (shadowing) объявлением параметра метода.
Остается вопрос, как в такой ситуации все же обратиться к полю класса. Если доступ по простому имени невозможен, надо воспользоваться составным. Здесь удобнее всего применить специальное ключевое слово this (оно будет подробно рассматриваться в следующих главах). Слово this имеет значение ссылки на объект, внутри которого оно применяется. Если вызвать метод setAge() у объекта класса Human и использовать в этом методе слово this, то его значение будет ссылкой на данный объект.
Исправленный вариант примера:
class Human {
int age; // возраст
void setAge(int age) {
this.age=age; // верное присвоение!
}
}
Конфликт имен, возникающий из-за затеняющего объявления, довольно легко исправить с помощью ключевого слова this или других конструкций языка, в зависимости от обстоятельств. Наибольшей проблемой является то, что компилятор никак не сообщает о таких ситуациях, и самое сложное – выявить ее с помощью тестирования или контрольного просмотра кода.
"Заслоняющее" объявление (Obscuring)
Может возникнуть ситуация, когда простое имя может быть одновременно рассмотрено как имя переменной, типа или пакета.
Приведем пример, который частично иллюстрирует такой случай:
import java.awt.*;
public class Obscuring {
static Point Test = new Point(3,2);
public static void main (String s[]) {
print(Test.x);
}
}
class Test {
static int x = -5;
}
В методе main() простое имя Test одновременно обозначает имя поля класса Obscuring и имя другого типа, находящегося в том же пакете,– Test. С помощью этого имени происходит обращение к полю x, которое определено и в классе java.awt.Point и Test.
Результатом этого примера станет 3, то есть переменная имеет более высокий приоритет. В свою очередь, тип имеет более высокий приоритет, чем пакет. Таким образом, обращение к доступному в обычных условиях типу или пакету может оказаться невозможным, если есть объявление одноименной переменной или типа, имеющее более высокий приоритет. Такое объявление называется "заслоняющим" (obscuring).
Эта проблема скорее всего не возникнет, если следовать соглашениям по именованию элементов языка Java.
