it-swarm.com.ru

Когда я должен использовать "это" в классе?

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

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

220
Roman

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

Случай 1: Использование this для устранения неоднозначности ссылок на переменные. В методах установки Java мы обычно передаем аргумент с тем же именем, что и закрытая переменная-член, которую мы пытаемся установить. Затем мы присваиваем аргумент xthis.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 для вызова альтернативных конструкторов. В комментариях 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, используемый, чтобы подчеркнуть тот факт, что на переменную экземпляра ссылаются (без необходимости устранения неоднозначности), но, на мой взгляд, это редкий случай.

300
William Brendel

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

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

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

42
froadie

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

22
Adam Robinson

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

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

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();
    }

}
10
Kieren Dixon

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

7
ChickenMilkBomb

Есть много хороших ответов, но есть еще одна очень незначительная причина повсеместно размещать 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 или проекта, если ваши правила включают «если кто-то открывает все эти исходные коды с помощью блокнота, он или она должен выстрелить себе в голову», то вы совершенно не можете этого делать this ,.

6
Jai

Ответ @William Brendel предоставил три разных варианта использования. 

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

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

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

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

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

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

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

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

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

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

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

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

3
Ravindra babu

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 вместо этого.

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

2
BlairHippo

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

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

https://docs.Oracle.com/javase/tutorial/Java/javaOO/thiskey.html

2
roottraveller

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; 
    }
}
1
nouman shah

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

1
giri

Будет ли какая-то разница, если я буду использовать «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() уточняет, что вызов сделан этим объектом.

0
amit

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's scope
      this.i = 9; // i refers to class variable
  }
0
doc

Что касается сообщений Уильяма Бренделя и dbconfessions вопроса относительно case 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");
    }
  }

}

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

0
Alija