Область дії об’єктів (scope). Видалення об’єктів. Переваги використання підходу “збору сміття” для об’єктів

Область дії об’єктів (scope). Видалення об’єктів. Переваги використання підходу “збору сміття” для об’єктів


Зміст



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.GetX(); // 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). Це, в свою чергу, спрощує програмування і зменшує ризик помилок.
“Збирач сміття” переглядає об’єкти і визначає ті, на які вже не має посилань. Після цього він видаляє пам’ять, виділену для цих об’єктів.


Зв’язані теми