Когда я должен использовать «это» в классе? - PullRequest
235 голосов
/ 09 марта 2010

Я знаю, что this относится к текущему объекту. Но я не знаю, когда мне действительно нужно это использовать. Например, будет ли какая-то разница, если я буду использовать x вместо this.x в некоторых методах? Может быть x будет ссылаться на переменную, которая является локальной для рассматриваемого метода? Я имею в виду переменную, которая видна только в этом методе.

А как насчет this.method()? Могу ли я использовать это? Должен ли я использовать это. Если я просто использую method(), не будет ли он по умолчанию применяться к текущему объекту?

Ответы [ 17 ]

314 голосов
/ 09 марта 2010

Ключевое слово this в основном используется в трех ситуациях. Первый и наиболее распространенный - в методах установки для устранения неоднозначности ссылок на переменные. Второе - это когда необходимо передать текущий экземпляр класса в качестве аргумента методу другого объекта. Третий способ вызова альтернативных конструкторов из конструктора.

Случай 1: Использование this для устранения неоднозначности ссылок на переменные. В методах установки Java мы обычно передаем аргумент с тем же именем, что и закрытая переменная-член, которую мы пытаемся установить. Затем мы присваиваем аргумент x на this.x. Это дает понять, что вы присваиваете значение параметра «имя» переменной экземпляра «имя».

public class Foo
{
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}

Случай 2: Использование this в качестве аргумента, передаваемого другому объекту.

public class Foo
{
    public String useBarMethod() {
        Bar theBar = new Bar();
        return theBar.barMethod(this);
    }

    public String getName() {
        return "Foo";
    }
}

public class Bar
{
    public void barMethod(Foo obj) {
        obj.getName();
    }
}

Случай 3: Использование this для вызова альтернативных конструкторов. В комментариях тринитис правильно указал на другое распространенное использование this. Если у вас есть несколько конструкторов для одного класса, вы можете использовать this(arg0, arg1, ...) для вызова другого конструктора по вашему выбору, если вы делаете это в первой строке вашего конструктора.

class Foo
{
    public Foo() {
        this("Some default value for bar");

        //optional other lines
    }

    public Foo(String bar) {
        // Do something with bar
    }
}

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

66 голосов
/ 09 марта 2010

Вторым важным использованием this (помимо сокрытия с локальной переменной, как уже сказано в многих ответах) является доступ к внешнему экземпляру из вложенного нестатического класса:

public class Outer {
  protected int a;

  public class Inner {
    protected int a;

    public int foo(){
      return Outer.this.a;
    }

    public Outer getOuter(){
      return Outer.this;
    }
  }
}
44 голосов
/ 09 марта 2010

Вам нужно только использовать this - и большинство людей используют его только - когда есть перекрывающаяся локальная переменная с тем же именем. (Методы установки, например.)

Конечно, еще одна веская причина для использования this заключается в том, что он вызывает всплывающую подсказку в IDE:)

23 голосов
/ 09 марта 2010

Для использования квалификатора this. требуется только * - это когда другая переменная в текущей области имеет такое же имя и вы хотите сослаться на элемент экземпляра (как описывает Вильям). Кроме того, нет никаких различий в поведении между x и this.x.

15 голосов
/ 09 марта 2010

«this» также полезно при вызове одного конструктора из другого:

public class MyClass {
    public MyClass(String foo) {
        this(foo, null);
    }
    public MyClass(String foo, String bar) {
        ...
    }
}
10 голосов
/ 28 июля 2011

this полезно в шаблоне строителя.

public class User {

    private String firstName;
    private String surname;

    public User(Builder builder){
        firstName = builder.firstName;
        surname = builder.surname;
    }

    public String getFirstName(){
        return firstName;
    }

    public String getSurname(){
        return surname;
    }

    public static class Builder {
        private String firstName;
        private String surname;

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setSurname(String surname) {
            this.surname = surname;
            return this;
        }

        public User build(){
            return new User(this);
        }

    }

    public static void main(String[] args) {
        User.Builder builder = new User.Builder();
        User user = builder.setFirstName("John").setSurname("Doe").build();
    }

}
7 голосов
/ 09 марта 2010

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

6 голосов
/ 22 февраля 2018

Есть много хороших ответов, но есть еще одна очень незначительная причина, чтобы ставить this везде. Если вы попытались открыть исходные коды в обычном текстовом редакторе (например, в блокноте и т. Д.), Использование this сделает его намного понятнее.

Представьте себе это:

public class Hello {
    private String foo;

    // Some 10k lines of codes

    private String getStringFromSomewhere() {
        // ....
    }

    // More codes

    public class World {
        private String bar;

        // Another 10k lines of codes

        public void doSomething() {
            // More codes
            foo = "FOO";
            // More codes
            String s = getStringFromSomewhere();
            // More codes
            bar = s;
        }
    }
}

Это очень ясно для чтения с любой современной IDE, но это будет полный кошмар для чтения с обычным текстовым редактором.

Вам будет трудно выяснить, где находится foo, пока вы не воспользуетесь функцией редактора "найти". Тогда вы будете кричать на getStringFromSomewhere() по той же причине. Наконец, после того, как вы забыли, что такое s, этот bar = s нанесет вам последний удар.

Сравните это с этим:

public void doSomething() {
    // More codes
    Hello.this.foo = "FOO";
    // More codes
    String s = Hello.this.getStringFromSomewhere();
    // More codes
    this.bar = s;
}
  1. Вы знаете, foo - это переменная, объявленная во внешнем классе Hello.
  2. Вы знаете, getStringFromSomewhere() - это метод, объявленный также во внешнем классе.
  3. Вы знаете, что bar принадлежит классу World, а s является локальной переменной, объявленной в этом методе.

Конечно, всякий раз, когда вы что-то разрабатываете, вы создаете правила. Таким образом, при разработке вашего API или проекта, если ваши правила включают «если кто-то открывает все эти исходные коды с помощью блокнота, он или она должен выстрелить себе в голову», то вы вполне можете не делать этого .

4 голосов
/ 17 сентября 2016

@ Уильям Брендель в ответе предложил три разных варианта использования.

Вариант использования 1:

Официальная страница документации Java на , эта предоставляет те же сценарии использования.

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

Он охватывает два примера:

Использование этого с полем и Использование этого с конструктором

Вариант использования 2:

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

synchronized(this){
    // Do some thing. 
}

Вариант использования 3:

Реализация шаблона Builder зависит от использования this для возврата измененного объекта.

Ссылка на этот пост

Удержание строителя в отдельном классе (свободный интерфейс)

2 голосов
/ 10 октября 2016

Ниже приведены способы использования этого ключевого слова в java:

  1. Использование ключевого слова this для ссылки на переменные экземпляра текущего класса
  2. Использование this() для вызова текущего конструктора класса
  3. Использование ключевого слова this для возврата текущего экземпляра класса
  4. Использование ключевого слова this в качестве параметра метода

https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

...