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


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