Область действия объектов (scope). Удаление объектов. Преимущества использования подхода «уборки мусора» для объектов

Область действия объектов (scope). Удаление объектов. Преимущества использования подхода «сборки мусора» (garbage collection) для объектов


Содержание



1. Как в Java определяется область действия переменных примитивного типа?

В языке программирования Java область действия (scope) переменных или объектов определяется положением фигурных скобок { }. Переменная, которая объявлена в пределах области действия, есть доступной только в этой области действия.

Например.

{
    double x; // доступна x
    x = 3.86;

    {
        double y; // доступны x, y
        x = 5.55;
        y = 7.393;

        {
            double z = 3.88; // доступны x, y, z
            x = 2.88;
            y = 33.22;
            z = 11.33;
        }

        // здесь z недоступно
        //z = 29.99; // ошибка
    }

    // здесь y - недоступно
    //y = 1000.05; // ошибка
    x = 13.23; // x - доступно, правильно
}

2. Можно ли во внутренней области действия «замещать» имя переменной примитивного типа, которая объявлена во внешней области действия?

В языке Java не допускается «замещать» имя переменной, которая объявлена во внешней области действия.

Например. В нижеследующем коде возникнет ошибка компиляции.

{

    double x = 2.88; // правильно

    {
        double x; // ошибка "Duplicate local variable x"
    }
}

В языках C/C++ подобный код не вызовет ошибки.

3. Можно ли давать одинаковые имена переменным, которые объявлены в разных областях действия?

Да.

Например. В нижеследующем коде объявляются переменные с одинаковыми именами, но которые размещаются в разных областях действия. Такой код работает.

{
    {
        double x = 2.88; // правильно
        System.out.println("x = " + x);
    }

    {
        double x; // и так можно
        x = 3.55;
        System.out.println("x = " + x);
    }

    System.out.println("OK!");
}

Результат работы программы:

x = 2.88
x = 3.55
OK!

4. Как определяется область действия для объектов? Какое отличие между областью действия примитивных типов и областью действия объектов?

При объявлении ссылки на объект, сама переменная-ссылка имеет область действия в пределах фигурных скобок { }. Если для объекта память была выделена оператором new, тогда сам объект будет существовать и после того, как исчезнет переменная-ссылка на него.

Например. Пусть задан класс CPoint.

class CPoint
{
    private int x, y;
    public CPoint(int nx, int ny) { x = nx; y = ny; }
    public int GetX() { return x; }
    public int GetY() { return y; }
}

В нижеследующем фрагменте кода объявляется ссылка на объект класса CPoint для которого память выделяется оператором new.

{
    // ...

    {
        CPoint pt1 = new CPoint(5, 6); // pt1 ссылается на экземпляр объекта, в котором x=5, y=6
        int d = pt1.Get(); // d = 5
    } // исчезают переменные pt1, d; а объект типа CPoint остается

    // здесь объект, который был создан в области действия { } еще пока что остается в памяти
    // если на него не будет ссылок, то он будет удален "уборщиком мусора" (garbage collector)

    // ...
}

Переменная-ссылка pt1 исчезает после фигурной закрывающей скобки }. Однако, объект, на который указывала переменная-ссылка, остается в памяти. Если на него не будет больше ссылок, то он будет удален «уборщиком мусора» (garbage collector).

В вышеприведенном фрагменте кода невозможно получить доступ к объекту после уничтожения переменной pt1. Поскольку, эта единственная ссылка на объект вышла за пределы видимости. Если нужно сохранить доступ к объекту, то в Java существуют способы копирования ссылок на объекты. Но это уже совсем другая тема.

5. Какие преимущества дает подход «сборки мусора» по сравнению с традиционными подходами, которые были реализованы в языках C/C++?

Подход, который используется в Java, дает несколько преимуществ сравнительно с языками программирования C/C++. В языках программирования C/C++ нужно вручную удалять память для ненужных объектов, созданных оператором new. Если этого не сделать, то возникнет «утечка памяти» или memory leak. В языке программирования Java не нужно следить за удалением выделенной памяти, это все сделает «уборщик мусора» (garbage collector). Это, в свою очередь, упрощает программирование и уменьшает риск ошибок.

«Сборщик мусора» просматривает объекты и определяет те, на которые уже не существует ссылок. После этого он удаляет память, выделенную для этих объектов.


Связанные темы