Область действия (scope) и время жизни (lifetime) переменных определяют, где к переменным можно получить доступ и как долго они хранятся в памяти. Область действия переменной — это область кода, где переменная видима и может быть использована. Время жизни переменной — это период, в течение которого она находится в памяти. Локальные переменные существуют только во время выполнения блока или метода, в котором они объявлены, и уничтожаются после завершения блока или метода. Переменные экземпляра класса существуют до тех пор, пока объект, которому они принадлежат, находится в памяти. Статические переменные существуют в течение всего времени существования программы. Рассмотрим эти моменты подробнее.
Область действия или scope — это область программы, в которой переменная доступна или видима.
В Java переменные могут иметь разные области действия в зависимости от места их объявления:
Переменные, объявленные внутри блока кода (заключённые в фигурные скобки {}), имеют локальную область действия и доступны только внутри этого блока. Они обычно используются для временного хранения и уничтожаются после выхода блока:
class Program{
// метод образует локальную область видимости
public static void main(String[] args) {
// Определяем локальную переменную
int x = 5;
// используем переменную x
System.out.println("x: " + x);
// блок образует другую локальную область видимости
{
// Еще одна локальная переменная
int y = 10;
System.out.println("y: " + y);
} // здесь область действия переменной y завершается
// System.out.println("y: " + y); // здесь использовать переменную y нельзя
} // здесь область действия переменной x завершается
// метод test образует новую локальную область видимости
public static void test() {
// System.out.println("x: " + x); // здесь использовать переменную x нельзя
}
}
Здесь переменная x определеная как локальная внутри метода main. Соответственно область ее действия (scope) ограничена этим методом, и скажем, в другом методе - методе test она недоступна.
Аналогично, переменная y также является локальной, но объявленна внутри вложенного блока, и ее область действия ограничена этим блоком. Попытка доступа к y вне этого блока приведет к ошибке компиляции, поскольку переменная в этом случае будет находиться вне своей области действия.
Переменные, объявленные на уровне класса (вне любого метода), являются глобальными переменными. Они доступны всем методам и конструкторам класса и ,таким образом, имеют глобальную область действия - область класса. Например:
class Person{
// Глобальая переменная (область действия класса)
String name;
// Конструктор
public Person(String name) {
this.name = name;
}
public void print() {
System.out.println("Name: " + name);
}
}
Здесь на уровне класса Person определена глобальная переменная name. Соответственно мы можем обращаться к этой переменной внутри любого метода класса, в любом месте класса.
В Java время жизни переменной определяется временем, в течение которого она находится в памяти. Локальные переменные, объявленные внутри метода или блока, имеют время жизни, ограниченное выполнением этого метода или блока, и уничтожаются после его завершения.
Глобальные переменные могут иметь два типа времени жизни:
Нестатические глобальные переменные (иначе переменные экземпляра/объекта) имеют время жизни, соответствующее времени жизни объекта, которому они принадлежат. Такие переменные создаются при создании объекта объекта и уничтожаются при сборке мусора.
Статические переменные (объявленные на уровне класса с ключевым словом static) имеют время жизни, охватывающее всю программу, поскольку они создаются при первой загрузке класса и уничтожаются при завершении программы.
Например:
class Program{
public static void main(String[] args) {
Person.printCount(); // Count: 0
Person bob = new Person("Bob");
{
Person tom = new Person("Tom");
tom.printName(); // Name: Tom
} // здесь формально завершается время жизни объекта tom и его переменной name
// чуть позже сборщик мусора удалит переменную tom и ее переменную name
bob.printName(); // Name: Bob
Person.printCount(); // Count: 2
} // здесь формально завершается время жизни объекта bob и его переменной name
} // здесь завершается время жизни статической переменной count
class Person{
String name; // время жизни - время жизни объекта
static int count = 0; // время жизни - время жизни программы
public Person(String name) {
this.name = name;
count++; // для теста увеличиваем счетчик объектов
}
public void printName() {
System.out.println("Name: " + name);
}
public static void printCount() {
System.out.println("Count: " + count);
}
}
Здесь в классе Person определены две глобальных переменных: name и count. Переменная name принадлежит объекту, поэтому будет создаваться отдельно для каждого объекта (при создании этого объекта) и уничтожается при уничтожении объекта. А переменная count является статической, поэтому будет уничтожаться при завершении программы.