it-swarm.com.de

Wann sollte ich "this" in einer Klasse verwenden?

Ich weiß, dass this auf ein aktuelles Objekt verweist. Aber ich weiß nicht, wann ich es wirklich brauche. Gibt es beispielsweise einen Unterschied, wenn ich x anstelle von this.x in einigen der Methoden verwende? Kann x auf eine Variable verweisen, die für die betrachtete Methode lokal ist? Ich meine Variable, die nur in dieser Methode zu sehen ist.

Was ist mit this.method()? Kann ich es benutzen? Soll ich es benutzen? Wenn ich nur method() benutze, wird es nicht standardmäßig auf das aktuelle Objekt angewendet?

220
Roman

Das Schlüsselwort this wird hauptsächlich in drei Situationen verwendet. Die erste und gebräuchlichste Methode sind Setter-Methoden, um Variablenverweise zu disambiguieren. Der zweite ist, wenn die aktuelle Klasseninstanz als Argument an eine Methode eines anderen Objekts übergeben werden muss. Die dritte Möglichkeit ist, alternative Konstruktoren aus einem Konstruktor heraus aufzurufen.

Fall 1: Verwenden Sie this, um Variablenverweise zu disambiguieren. In Java-Setter-Methoden übergeben wir normalerweise ein Argument mit demselben Namen wie die private Member-Variable, die Sie setzen möchten. Dann weisen wir das Argument x dem this.x zu. Dadurch wird deutlich, dass Sie der Instanzvariablen "name" den Wert des Parameters "name" zuweisen.

public class Foo
{
    private String name;

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

Case 2: Verwenden von this als Argument, das an ein anderes Objekt übergeben wird.

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

Fall 3: Mit this können alternative Konstruktoren aufgerufen werden. In den Kommentaren wies Trinithis auf eine andere häufige Verwendung von this hin. Wenn Sie über mehrere Konstruktoren für eine einzelne Klasse verfügen, können Sie mit this(arg0, arg1, ...) einen anderen Konstruktor Ihrer Wahl aufrufen, sofern Sie dies in der ersten Zeile Ihres Konstruktors tun.

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

        //optional other lines
    }

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

Ich habe auch gesehen, dass this verwendet wurde, um die Tatsache hervorzuheben, dass auf eine Instanzvariable verwiesen wird (ohne Disambiguierung), aber das ist meiner Meinung nach selten.

300
William Brendel

Die zweite wichtige Verwendung von this (neben dem Ausblenden mit einer lokalen Variablen, wie es bereits viele Antworten sagen) ist der Zugriff auf eine äußere Instanz von einer verschachtelten nicht-statischen Klasse:

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

Sie müssen nur this verwenden - und die meisten verwenden es nur, wenn sich eine überlappende lokale Variable mit demselben Namen befindet. (Setzermethoden zum Beispiel.)

Natürlich ist ein weiterer guter Grund, this zu verwenden, dass Intellisense in IDEs auftaucht :)

42
froadie

Das einzige need , um das Qualifikationsmerkmal this. zu verwenden, ist, wenn eine andere Variable innerhalb des aktuellen Bereichs denselben Namen verwendet und Sie auf das Instanzmitglied verweisen möchten (wie William beschreibt). Abgesehen davon gibt es keinen Unterschied im Verhalten zwischen x und this.x.

22
Adam Robinson

"this" ist auch nützlich, wenn ein Konstruktor von einem anderen aufgerufen wird:

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

this ist im Builder-Muster hilfreich.

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

Wenn Sie nicht überlappende Variablennamen haben, dient dies nur der Klarheit beim Lesen des Codes.

7
ChickenMilkBomb

Es gibt viele gute Antworten, aber es gibt noch einen sehr geringen Grund, this überall einzusetzen. Wenn Sie versucht haben, Ihre Quellcodes mit einem normalen Texteditor (z. B. Notepad usw.) zu öffnen, wird die Verwendung von this deutlich lesbarer.

Stell dir das vor:

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

Das ist mit jeder modernen IDE zu lesen, aber es ist ein absoluter Albtraum, den Sie mit einem normalen Texteditor lesen können.

Sie werden nur schwer herausfinden können, wo sich foo befindet, bis Sie die "find" -Funktion des Editors verwenden. Dann schreien Sie aus dem gleichen Grund bei getStringFromSomewhere(). Schließlich, nachdem Sie vergessen haben, was s ist, wird bar = s Ihnen den letzten Schlag versetzen.

Vergleichen Sie es damit:

public void doSomething() {
    // More codes
    Hello.this.foo = "FOO";
    // More codes
    String s = Hello.this.getStringFromSomewhere();
    // More codes
    this.bar = s;
}
  1. Sie wissen, dass foo eine in der äußeren Klasse Hello deklarierte Variable ist.
  2. Sie wissen, getStringFromSomewhere() ist auch eine in der äußeren Klasse deklarierte Methode.
  3. Sie wissen, dass bar zur World-Klasse gehört und s eine in dieser Methode deklarierte lokale Variable ist.

Wenn Sie etwas entwerfen, erstellen Sie natürlich Regeln. Wenn Sie also beim Entwurf Ihrer API oder Ihres Projekts folgende Regeln enthalten: "Wenn jemand alle diese Quellcodes mit einem Notizblock öffnet, sollte er oder sie sich selbst in den Kopf schießen", dann ist es völlig in Ordnung, this nicht zu tun. .

6
Jai

@ William Brendel antwort stellte drei verschiedene Anwendungsfälle auf nette Weise zur Verfügung. 

Anwendungsfall 1:

Offizielle Java-Dokumentationsseite auf this bietet dieselben Anwendungsfälle. 

Innerhalb einer Instanzmethode oder eines Konstruktors ist dies eine Referenz auf das aktuelle Objekt - das Objekt, dessen Methode oder Konstruktor aufgerufen wird. Sie können auf dieses Element innerhalb einer Instanzmethode oder eines Konstruktors auf ein beliebiges Element des aktuellen Objekts verweisen.

Es werden zwei Beispiele behandelt: 

Verwendung mit einem Feld und Verwendung mit einem Konstruktor

Anwendungsfall 2:

Ein anderer Anwendungsfall, der in diesem Beitrag nicht zitiert wurde: this kann verwendet werden, um das aktuelle Objekt in einer Multithread-Anwendung zu synchronisieren, um kritische Abschnitte von Daten und Methoden zu schützen.

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

Anwendungsfall 3:

Die Implementierung von Builder pattern hängt von der Verwendung von this ab, um das geänderte Objekt zurückzugeben.

Siehe diesen Beitrag

Builder in separaten Klassen (fließende Schnittstelle)

3
Ravindra babu

Google hat auf der Sun-Website eine Seite aufgerufen, auf der dies ein wenig erläutert wird.

Sie haben Recht mit der Variablen. this kann tatsächlich verwendet werden, um eine Methodenvariable von einem Klassenfeld zu unterscheiden.


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

Ich hasse diese Konvention wirklich . Zwei verschiedene Variablen mit buchstäblich identischen Namen zu versehen, ist ein Rezept für Fehler. Ich bevorzuge etwas in der Art von:


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

Gleiche Ergebnisse, aber ohne die Möglichkeit eines Fehlers, bei dem Sie versehentlich auf x verweisen, wenn Sie wirklich beabsichtigten, stattdessen auf x zu verweisen.

Wenn Sie es mit einer Methode verwenden, haben Sie Recht mit den Effekten. Sie erhalten die gleichen Ergebnisse mit oder ohne. Kannst du es benutzen? Sicher. Solltest du es benutzen? Bis zu Ihnen, aber da ich persönlich denke, dass es sinnlose Ausführlichkeit ist, die keine Klarheit schafft (es sei denn, der Code ist voll mit statischen Importanweisungen), bin ich nicht geneigt, ihn selbst zu verwenden.

2
BlairHippo

Nachfolgend sind die Möglichkeiten aufgeführt, dieses "Schlüsselwort" in Java zu verwenden:

  1. Verwenden des this-Schlüsselworts zum Verweisen auf aktuelle Klasseninstanzvariablen
  2. Verwenden von this() zum Aufrufen des aktuellen Klassenkonstruktors
  3. Verwenden Sie das Schlüsselwort this, um die aktuelle Klasseninstanz zurückzugeben
  4. Verwenden Sie das Schlüsselwort this als Methodenparameter

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

2
roottraveller

this ist eine Referenz auf das aktuelle Objekt. Sie wird im Konstruktor verwendet, um zwischen der lokalen und der aktuellen Klassenvariablen zu unterscheiden, die denselben Namen haben. z.B.:

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

this kann auch verwendet werden, um einen Konstruktor von einem anderen Konstruktor aus aufzurufen. z.B.: 

public class circle {
    int x;

    circle() { 
        this(1);
    }

    circle(int x) {
        this.x = x; 
    }
}
1
nouman shah

wenn es zwei Variablen gibt, eine Instanzvariable und eine andere lokale Variable mit demselben Namen, verwenden wir diese. auf das aktuell ausgeführte Objekt verweisen, um den Konflikt zwischen den Namen zu vermeiden.

1
giri

Gibt es einen Unterschied, wenn ich in einigen Methoden "x" anstelle von "this.x" verwende?

Normalerweise nicht. Aber manchmal macht es einen Unterschied:

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

Wenn ich nur "method ()" verwende, wird es nicht standardmäßig auf das aktuelle Objekt angewendet?

Ja. Bei Bedarf stellt this.method() jedoch klar, dass der Aufruf von diesem Objekt ausgeführt wird.

0
amit

this hat keinen Einfluss auf den resultierenden Code - es ist der Operator für die Kompilierungszeit und der mit oder ohne generierte Code ist derselbe. Wann Sie es verwenden müssen, hängt vom Kontext ab. Zum Beispiel müssen Sie es verwenden, wie Sie sagten, wenn Sie über eine lokale Variable verfügen, die Klassenvariable überschattet und Sie auf Klassenvariable verweisen möchten und nicht auf lokale.

edit: Mit "resultierender Code wird derselbe sein", meine ich natürlich, wenn eine Variable im lokalen Gültigkeitsbereich die zur Klasse gehörende nicht verdeckt. Somit

class POJO {
   protected int i;

   public void modify() {
      i = 9;
   }

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

der resultierende Code beider Methoden ist derselbe. Der Unterschied besteht darin, dass eine Methode eine lokale Variable mit demselben Namen deklariert

  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

In Bezug auf William Brendel s Beiträge und dbconfessions Frage, betreffend case 2. Hier ist ein Beispiel:

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

}

Ich habe gesehen, wie dies beim Erstellen von Eltern-Kind-Beziehungen mit Objekten verwendet wurde. Beachten Sie jedoch, dass es der Kürze halber vereinfacht ist.

0
Alija