Для чего используется затенение переменных в классе Java?

Я читаю книгу "Как программировать на языке Java" и наткнулся на термин " слежка". Если теневое копирование разрешено, какая ситуация или какова его цель в классе Java?

Пример:

public class Foo {

    int x = 5;

    public void useField() {
        System.out.println(this.x);
    }
    public void useLocal() {
        int x = 10;
        System.out.println(x);
    }
}

5 ответов

Решение

Основное назначение теневого копирования - отделить локальный код от окружающего класса. Если это не было доступно, рассмотрите следующий случай.

Класс Foo в API выпущен. В вашем коде вы создаете его подкласс, а в вашем подклассе используется переменная bar. Затем Foo выпускает обновление и добавляет в свой класс защищенную переменную с именем Bar.

Теперь ваш класс не будет работать из-за конфликта, который вы не могли предвидеть.

Однако не делайте этого нарочно. Только позвольте этому случиться, когда вы действительно не заботитесь о том, что происходит за рамками.

Это может быть полезно для сеттеров, когда вам не нужно создавать отдельное имя переменной только для параметра метода, например:

public void setX(int x) {
    this.x = x;
}

Кроме того, я бы их избегал.

Одна из главных целей - запутать людей. Это плохая практика, и ее следует избегать.

Затенение на самом деле не только термин Java. В любом случае, когда переменная, объявленная в области видимости, имеет то же имя, что и переменная в большей области видимости, эта переменная затеняется.

Некоторое общее использование для теневого копирования - это когда у вас есть внутренние и внешние классы и вы хотите сохранить переменную с тем же именем.

Если вы можете избежать этого, вы должны это сделать, так как это может вызвать путаницу.

Два общих применения - это конструкторы и методы set:

public Foo(int x) {
    this.x = x;
}

public void setX(int x) {
    this.x = x;
}

В некоторых случаях это полезно, если вы хотите скопировать переменную в один момент, но эта переменная может измениться в вызове метода.

private void fire() {
    Listener[] listeners = this.listeners;
    int num = listeners.length;
    for (int ct=0; ct<num; ++ct) {
        listeners[ct].stateChanged();
    }
}

(Конечно, надуманный пример сделал ненужным с помощью шикарного цикла.)

Другие вопросы по тегам