Java — когда это единственный выход?

Следующий код выполняется как для var = putVar;, так и для this.var = putVar;

Я понимаю: «это» используется для идентификации этого - «поставьте это значение только для« моего »объекта». Когда оба работают, почему люди обычно используют «это» в сеттерах?

код:

public class PlayingWithObjects
{
    public static void main(String[] args)
    {
        SomeClass classObj = new SomeClass(10);

        System.out.println("classObj.getVar: " + classObj.getVar() );

        classObj.setVar(20);

        System.out.println("classObj.getVar: " + classObj.getVar() );

        classObj = new SomeClass(30);

        System.out.println("classObj.getVar: " + classObj.getVar() );
    }
}

class SomeClass
{
    private int var;

    public SomeClass(int putVar)
    {
        var = putVar;
    }

    public int getVar()
    {
        return var;
    }

    public void setVar(int putVar)
    {
//      var = putVar;           // also works
        this.var = putVar;
    }
}

Я правильно понимаю "это"? Где «это» используется и не может быть заменено. Пожалуйста, опубликуйте код.


person MdT    schedule 30.03.2013    source источник
comment
Обычно просто для того, чтобы было ясно, что они относятся к члену текущего объекта.   -  person Tushar    schedule 30.03.2013
comment
@Tushar: так что это просто хорошая практика - использовать this.var в конструкторах и сеттерах? есть ли у этого другие применения?   -  person MdT    schedule 30.03.2013
comment
В вашем случае, когда локальная переменная и член объекта имеют разные идентификаторы, это основной. Если вы находитесь в анонимном внутреннем классе внутри другого объекта (например, класса ClassName), вы можете использовать ClassName.this для получения экземпляра окружающего объекта. Причина этого (не каламбур) в том, что внутри внутреннего класса this будет ссылаться на внутренний класс.   -  person Tushar    schedule 30.03.2013
comment
Может быть, этот вопрос поможет   -  person Rahul Gautam    schedule 30.03.2013
comment
«Почему люди обычно используют «это» в сеттерах?» Они делают? Свидетельство? Я да, но я всегда использую одно и то же имя в параметрах, так что я должен. Я не знаю, что люди «обычно» делают.   -  person user207421    schedule 31.03.2013


Ответы (5)


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

public void setX(int x) {
    this.x = x;
}
person ktm5124    schedule 30.03.2013
comment
В этом примере говорят, что x, переданный в метод, затеняет x, хранящийся в экземпляре. - person Cory Kendall; 30.03.2013

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

Неиспользование одного и того же имени является более распространенной практикой, чтобы избежать путаницы и затенения. Следовательно, любая ссылка на this в установщике может быть заменена более подходящим стандартом именования: например, inParameter.

public void setX(int inX) {
    x = inX;
}

Другое использование this может заключаться в явном вызове конструктора. Это форма, которую нельзя заменить более простым соглашением об именах:

public class Foo {

    private String name;

    public Foo() {
        this("");
    }

    public Foo(String inName) {
        name = inName;
    }
}

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

return this;
person Makoto    schedule 30.03.2013
comment
Верно, вызова конструктора мне не хватало. - person Tushar; 30.03.2013
comment
Здесь мне нужна помощь. Можете ли вы привести простой пример, где я бы вернул это; - person MdT; 30.03.2013
comment
Хороший пример возврата this — это когда вы хотите реализовать цепочку методов (Google App Engine делает это с построением запросов, IIRC). - person ktm5124; 30.03.2013

Есть 2 случая, о которых я знаю, помимо упомянутого случая ktm (который я думаю очевиден, и вы уже знали):

  1. Просто чтобы было ясно, что они относятся к члену текущего объекта.

    void foo(int x) {
        this.y = x; // No mistaking that y belongs to the object
    }
    
  2. Если вы находитесь в анонимном внутреннем классе внутри другого объекта (например, класса ClassName), вы можете использовать ClassName.this, чтобы получить экземпляр окружающего объекта. Причина этого (без каламбура) в том, что внутри внутреннего класса this будет относиться к внутреннему классу.

    SomeInnerClass myObj = new SomeInnerClass() {
        void bar() {
            this.y = 0; // this refers to the SomeInnerClass object
            OuterClass.this.y = 0; // OuterClass.this refers to the enclosing class OuterClass object
        }
    };
    
person Tushar    schedule 30.03.2013

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

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

просто установит параметр на себя, а не установит поле на параметр.

person osandov    schedule 30.03.2013

Если в классе есть переменная экземпляра с каким-то именем (скажем, myVar), а в методе есть ЛОКАЛЬНАЯ переменная с точно таким же именем (myVar), то любая ссылка на переменную будет ссылаться на ЛОКАЛЬНУЮ переменную. В таких случаях, если мы хотим указать переменную экземпляра класса, нам нужно сказать this.myVar. Как указывалось ранее, это особенно полезно, когда мы хотим иметь сеттеры, в которых имя параметра совпадает с переменной экземпляра, которую он устанавливает:

public void setMyVar(int myVar) {
    this.myVar = myVar; // If we said myVar = myVar;, we'd just set the local
                        // variable to itself, which would NOT be what we want.
}
person Jimmy Lee    schedule 30.03.2013