Когда следует использовать "this" в классе?

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

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

Ответ 1

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

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

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 для вызова альтернативных конструкторов. В комментариях trinithis правильно указано другое общее использование 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 используется для того, чтобы подчеркнуть тот факт, что ссылка на экземпляр указана (без необходимости устранения неоднозначности), но это редкий случай, на мой взгляд.

Ответ 2

Второе важное использование 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;
    }
  }
}

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

public class MyClass {
    public MyClass(String foo) {
        this(foo, null);
    }
    public MyClass(String foo, String bar) {
        ...
    }
}

Ответ 6

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

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

Ответ 8

Google запустил страницу на сайте Sun, где это немного обсуждается.

Вы правы в переменной; this действительно может использоваться для дифференциации переменной метода из поля класса.


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

Однако, я действительно ненавижу это соглашение. Предоставление двух разных переменных буквально одинаковых имен - это рецепт ошибок. Я предпочитаю что-то вроде:


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

Те же результаты, но без каких-либо ошибок, когда вы случайно ссылаетесь на x, когда вы действительно хотели ссылаться на x.

Что касается использования этого метода, вы правы в отношении эффектов; вы получите те же результаты с или без него. Вы можете использовать его? Конечно. Должны ли вы использовать его? До вас, но, учитывая, что я лично считаю это бессмысленной многословностью, которая не добавляет никакой ясности (если код не заполнен статическими операторами импорта), я не склонен использовать его сам.

Ответ 9

@Ответ Виллиама Бренделя предоставил три разных варианта использования красивым способом.

Использовать случай 1:

Страница документации по официальной java на this предоставляет те же варианты использования.

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

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

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

Использовать случай 2:

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

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

Использовать случай 3:

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

Обратитесь к этому сообщению

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

Ответ 10

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

Ответ 11

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

public class circle {
    int x;
    circle(int x){
        this.x =x;
        //class variable =local variable 
    }
} 

this также может использоваться для вызова одного конструктора из другого конструктора. например:

public class circle {
    int x;

    circle() { 
        this(1);
    }

    circle(int x) {
        this.x = x; 
    }
}

Ответ 12

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

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

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

Ответ 13

Будет ли какая-либо разница, если я использую "x" вместо "this.x" в некоторых методах?

Обычно нет. Но иногда это имеет значение:

  class A {
     private int i;
     public A(int i) {
        this.i = i; // this.i can be used to disambiguate the i being referred to
     }
  }

Если я просто использую метод "method()", не будет ли он по умолчанию применяться к текущему объекту?

Да. Но при необходимости this.method() разъясняет, что вызов выполняется этим объектом.

Ответ 14

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

edit: "результирующий код будет одним и тем же". Я имею в виду, конечно, когда какая-то переменная в локальной области не скрывает того, что принадлежит классу. Таким образом,

class POJO {
   protected int i;

   public void modify() {
      i = 9;
   }

   public void thisModify() {
      this.i = 9;
   }
}

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

  public void m() {
      int i;
      i = 9;  // i refers to variable in method scope
      this.i = 9; // i refers to class variable
  }

Ответ 15

Относительно сообщений и вопросов dbconfessions относительно случая 2. Вот пример:

public class Window {

  private Window parent;

  public Window (Window parent) {
    this.parent = parent;
  }

  public void addSubWindow() {
    Window child = new Window(this);
    list.add(child);
  }

  public void printInfo() {
    if (parent == null) {
      System.out.println("root");
    } else {
      System.out.println("child");
    }
  }

}

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

Ответ 16

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

Если ваш объект не связан с безопасностью потоков, нет причин указывать, какое значение элемента объекта используется.