Область видимости
Область видимости — часть программы, в которой переменная доступна по имени. В Java она определяется фигурными скобками: переменная живёт от места объявления до конца блока, в котором объявлена.
Локальные переменные
Переменная, объявленная внутри метода, называется локальной. Она видна только в этом методе, и другие методы не могут к ней обратиться:
void main() {
String message = "Привет";
IO.println(message);
printTwice();
}
void printTwice() {
String message = "Пока";
IO.println(message + " " + message);
}Результат:
Привет
Пока ПокаДве переменные message никак не связаны: каждая принадлежит своему методу. Параметры метода тоже локальные переменные.
Блоки
Переменная, объявленная внутри блока if или цикла, исчезает после закрывающей скобки. Если значение нужно после блока, объявите переменную до него:
void main() {
int age = 20;
String status;
if (age >= 18) {
String note = "совершеннолетний";
status = note;
} else {
status = "несовершеннолетний";
}
IO.println(status);
}Результат:
совершеннолетнийПеременная note за пределами блока if уже не существует, а status объявлена снаружи и доступна дальше.
Переменная цикла
Счётчик, объявленный в заголовке for, виден только внутри цикла. Поэтому в соседних циклах можно снова использовать имя i:
void main() {
for (int i = 0; i < 2; i++) {
IO.print("A" + i + " ");
}
for (int i = 0; i < 2; i++) {
IO.print("B" + i + " ");
}
IO.println();
}Результат:
A0 A1 B0 B1Поля программы
Переменная, объявленная вне всех методов, называется полем. Её видят все методы файла, и она хранит значение между вызовами:
int visits = 0;
void visit() {
visits++;
}
void main() {
visit();
visit();
visit();
IO.println("Посещений: " + visits);
}Результат:
Посещений: 3Поля удобны, но их значение может изменить любой метод, поэтому за ними сложнее следить. Если данные нужны одному методу, делайте переменную локальной.
Затенение
Если локальная переменная называется так же, как поле, внутри метода она затеняет поле: по имени будет доступна локальная. К полю тогда обращаются через this.:
String name = "Поле";
void main() {
String name = "Локальная";
IO.println(name);
IO.println(this.name);
}Результат:
Локальная
ПолеСлово this означает текущий объект — о нём подробнее в главе об ООП.
Частая ошибка
Переменная, объявленная внутри блока, не видна после него. Компилятор сообщает, что не может найти имя:
void main() {
for (int i = 0; i < 3; i++) {
int square = i * i;
}
IO.println(square);
}Результат:
Main.java:5: error: cannot find symbol
IO.println(square);
^
symbol: variable square
location: class Main
1 error
error: compilation failedОбъявите переменную до цикла, а внутри только присваивайте ей значение.