Иллюстрированный самоучитель по Java
Где
видны переменные
В языке Java нестатические переменные
можно объявлять в любом месте кода между операторами. Статические переменные
могут быть только полями класса, а значит, не могут объявляться внутри методов
и блоков. Какова же
область видимости
(scope) переменных? Из каких методов
мы можем обратиться к той или иной переменной? В каких операторах использовать?
Рассмотрим на примере листинга 2.6 разные случаи объявления переменных.
Листинг 2.6.
Видимость и инициализация переменных
class
ManyVariables{
static
int x = 9, у; // Статические переменные — поля класса
// Они известны во всех методах и блоках класса
// Переменная у получает значение 0
static{
// Блок инициализации статических переменных
// Выполняется один раз при первой загрузке класса после
// инициализаций в объявлениях переменных
х = 99;
// Оператор выполняется вне всякого метода!
}
int а = 1, р;
// Нестатические переменные — поля экземпляра
// Известны во всех методах и блоках класса, в которых они
//не перекрыты другими переменными с тем же именем
// Переменная р получает значение 0
{
// Блок инициализации экземпляра
// Выполняется при создании, каждого экземпляра после
// инициализаций при объявлениях переменных
р = 999;
// Оператор выполняется вне всякого метода!
}
static void f(int
b){ // Параметр метода b — локальная
// переменная, известна только внутри метода
int a = 2;
// Это вторая переменная с тем же именем "а"
// Она известна только внутри метода f() и
// здесь перекрывает первую "а"
int с;
// Локальная переменная, известна только в методе f()
//Не получает никакого начального значения
//и должна быть определена перед применением
{ int с = 555;
// Ошибка! Попытка повторного объявления
int х = 333;
// Локальная переменная, известна только в этом блоке
}
// Здесь переменная
х уже неизвестна
for (int d =
0; d < 10; d++){
// Переменная
цикла d известна только в цикле
int а =
4; // Ошибка!
int e =
5; // Локальная переменная, известна только в цикле for
е++;
// Инициализируется при каждом выполнении цикла
System.out.println("e
= " + e) ; // Выводится всегда "е = 6"
}
// Здесь переменные
d и е неизвестны
}
public static
void main(String!] args){
int a =
9999; // Локальная переменная, известна
// только внутри метода main()
f (a);
}
}
Обратите внимание на то, что переменным
класса и экземпляра неявно присваиваются нулевые значения. Символы неявно получают
значение
'\u0000'
, логические переменные — значение
false
,
ссылки получают неявно значение
null
.
Локальные же переменные неявно не
инициализируются. Им должны либо явно присваиваться значения, либо они обязаны
определяться до первого использования. К счастью, компилятор замечает неопределенные
локальные переменные и сообщает о них.
Внимание
Поля класса при объявлении обнуляются,
локальные переменные автоматически не инициализируются.
В листинге 2.6 появилась еще одна
новая конструкция:
блок инициализации экземпляра
(instance initialization).
Это просто блок операторов в фигурных скобках, но записывается он вне всякого
метода, прямо в теле класса. Этот блок выполняется при создании каждого экземпляра,
после инициализации при объявлении переменных, но до выполнения конструктора.
Он играет такую же роль, как и static-блок для статических переменных. Зачем
же он нужен, ведь все его содержимое можно написать в начале конструктора? В
тех случаях, когда конструктор написать нельзя, а именно, в безымянных внутренних
классах.