Was ist der akzeptierte Stil für die Verwendung des Schlüsselworts "this" in Java?

37

Ich komme aus Sprachen wie Python oder Javascript (und anderen, die weniger objektorientiert sind) und versuche, meine Java-Kenntnisse, die ich nur oberflächlich kenne, zu verbessern.

Wird es als schlechte Praxis angesehen, immer thisden aktuellen Instanzattributen voran zu stellen? Es fühlt sich für mich natürlicher an zu schreiben

...
private String foo;

public void printFoo() {
    System.out.println(this.foo);
}
...

als

...
private String foo;

public void printFoo() {
    System.out.println(foo);
}
...

da es mir hilft, Instanzattribute von lokalen Variablen zu unterscheiden.

Natürlich ist es in einer Sprache wie Javascript sinnvoller, immer zu verwenden this, da man mehr Funktionen verschachteln kann und daher lokale Variablen aus größeren Bereichen stammen. In Java ist, soweit ich weiß, keine solche Verschachtelung möglich (außer in inneren Klassen), daher ist dies wahrscheinlich kein großes Problem.

In jedem Fall würde ich lieber verwenden this. Würde es sich komisch und nicht idiomatisch anfühlen?

Andrea
quelle
Wir verwenden ein Tool, um dies in unserem Unternehmen zu standardisieren. Der Tool Rerite Code ist bei uns ohne diesen je nach Firmenpolitik. Daher codiert jeder, wie er möchte, und der Code wird zum Festschreibungszeitpunkt richtig formatiert.
Deadalnix
2
"Da man mehr Funktionen verschachteln kann, stammen lokale Variablen aus größeren Bereichen." Die Tatsache, dass "dies" nicht der Ort ist, an dem eine nicht qualifizierte Variable in einer Funktion in JS vorkommt.
Random832
2
Ich stelle allen Instanzvariablen einen Unterstrich voran, damit ich den Unterschied zwischen lokalen und Instanzvariablen leicht erkennen kann, ohne sie zu verwenden this.
WuHoUnited
4
In C # möchte StyleCop, dass Sie this.bei der Bezugnahme auf Member-Variablen, Methoden usw. Ich mag das, ich stimme dieser Regel zu. Ich denke, es ist besser, als etwas mit einem Unterstrich am Anfang zu benennen. Ich würde die gleiche Regel befolgen, wenn ich in Java codieren würde.
Job

Antworten:

40

In den meisten IDEs können Sie einfach mit der Maus über die Variable fahren, wenn Sie dies wissen möchten. Wenn Sie in einer Instanzmethode arbeiten, sollten Sie wirklich alle beteiligten Variablen kennen. Wenn Sie zu viele haben oder deren Namen nicht übereinstimmen, müssen Sie eine Umgestaltung durchführen.

Es ist wirklich ziemlich überflüssig.

DeadMG
quelle
7
Außerdem sollte eine vernünftige IDE Felder und lokale Variablen / Parameter visuell voneinander unterscheiden. Beispielsweise sind in Eclipse (standardmäßig) Felder blau, während lokale Variablen schwarz sind.
Joachim Sauer
1
@Joachim Netter Punkt, Eclipse kann sogar Parameter und lokale Variablen unterschiedlich färben, wenn der Benutzer dies wünscht (dies ist jedoch nicht die Standardeinstellung).
Eric-Karl,
3
Obwohl ich zustimme, finde ich, wenn ich auf den Code anderer Entwickler stoße (und zwar auf den ersten Blick ungewohnt), this.viel hilfreicher. Dies liegt wahrscheinlich auch daran, dass ich keine IDE besitze, die lokale / Objektvariablen unterschiedlich farbcodiert.
Brad Christie
3
+1 für (paraphrasieren) „Refactoring , wenn Sie verwenden müssen , diese zu schließen , dass es ein Mitglied ist“. Genau das, worauf ich hinweisen wollte.
Yam Marcovic
Ich finde nicht, dass es das Lesen erschwert, und im Gegenzug bleibt der Code in Editoren mit weniger ausgefeilten Syntaxhervorhebungen, die nicht zwischen Feldern und Einheimischen unterscheiden, lesbar. Ich war immer der Meinung, dass Sie sich bemühen sollten, dass Ihr Code im einfachsten Texteditor leicht lesbar ist, und wenn dies nicht der Fall ist, sollte es einen guten Grund dafür geben.
Kevin
26

Ich benutze lieber this. Es erleichtert das Lesen von Code in verschiedenen Editoren, die lokale Variablen und Instanzvariablen auf dieselbe Weise färben. Es erleichtert auch das Lesen des Codes auf einer gedruckten Seite während einer Codeüberprüfung. Es ist auch eine ziemlich starke Erinnerung an den Umfang der Variablen für andere Entwickler.

Es gibt jedoch Argumente dagegen. In modernen IDEs können Sie den Gültigkeitsbereich einer Variablen ermitteln, indem Sie den Mauszeiger darüber halten oder sie in einer baumartigen Struktur anzeigen. Sie können auch die Farbe und / oder die Schriftart von Variablen in Abhängigkeit von ihrem Umfang ändern (auch so, dass beim Drucken ersichtlich ist, wie der Umfang der Variablen ist).

Ich glaube, dass ChrisFs letzter Satz tot ist: Seien Sie konsequent in Ihrer Verwendung.

Thomas Owens
quelle
7
"Es ist auch eine ziemlich starke Erinnerung an den Umfang der Variablen für andere Entwickler." - der Grund, den ich benutze und gerne this.im Code sehe . Das Schreiben dauert eine halbe Sekunde und kann lange Zeit in Anspruch nehmen, wenn Sie herausfinden müssen, ob der Typ vor Ihnen wirklich die Pascal-Case-Eigenschaft anstelle der lokalen Camel-Case-Eigenschaft verwenden wollte, als er vor 20 Revisionen in letzter Minute Änderungen vorgenommen hat.
scrwtp
18

Ein Ort, den ich konsequent benutze, sind Setter und / oder Konstruktoren:

public void setFoo(String foo) {
    this.foo = foo;
}

Abgesehen davon halte ich es nicht für notwendig, es hinzuzufügen. Beim Lesen des Hauptteils einer Methode sind Parameter und Locals genau dort - und ziemlich einfach zu verfolgen (auch ohne die IDE-Hilfe). Auch Einheimische und Felder neigen dazu, unterschiedlicher Natur zu sein (Objektzustand vs. transienter Speicher oder Parameter).

Wenn Sie sich nicht sicher sind, was eine Variable und was ein Feld ist, bedeutet dies wahrscheinlich, dass eine Methode zu viele Variablen / Parameter enthält, zu lang und zu komplex ist und vereinfacht werden sollte.

Wenn Sie "this" zum Kennzeichnen von Feldern verwenden, würde ich empfehlen, sicherzustellen, dass die Konvention immer genau befolgt wird. Es wäre wirklich einfach anzunehmen, dass "no" bedeutet, dass es sich um ein lokales und auf der Annahme basierendes Teil handelt.

edit: Ich verwende dies auch in equals, clone oder irgendetwas, das einen 'that'-Parameter desselben Objekttyps hat:

public boolean isSame(MyClass that) {
    return this.uuid().equals(that.uuid());
}
ptyx
quelle
8

Es ist fraglich.

Unter Verwendung von C # als Analogie, da es eine sehr ähnliche Syntax und Struktur wie Java hat, stellen wir fest, dass C # StyleCop eine Standardregel enthält, die Sie hinzufügen müssen this, aber ReSharper hat eine Standardregel, die besagt, dass das thisredundant ist (was es ist) und sein kann entfernt.

Wenn Sie also ein Tool verwenden, fügen Sie es hinzu, wenn Sie ein anderes Tool verwenden, entfernen Sie es. Wenn Sie beide Tools verwenden, müssen Sie eine der Regeln auswählen und deaktivieren.

Was jedoch die Regeln bedeuten, ist, dass Sie in Ihrer Verwendung konsequent sind - was wahrscheinlich das wichtigste ist.

ChrisF
quelle
8

Wird es als schlechte Praxis angesehen, dies immer den aktuellen Instanzattributen voranzustellen?

Ja - von einigen, nein - von anderen.

Ich mag und benutze thisSchlüsselwörter in meinen Projekten in Java und C #. Man kann argumentieren, dass IDE Parameter und Felder immer durch unterschiedliche Farben hervorhebt, wir arbeiten jedoch nicht immer in IDE - wir müssen viele Zusammenführungen / Unterschiede / einige schnelle Änderungen in einem Notizblock vornehmen / einige Codeausschnitte in E-Mails überprüfen . Es ist viel einfacher für mich, auf den ersten Blick zu erkennen, wo sich der Status der Instanz ändert - zum Beispiel, um einige mögliche Parallelitätsprobleme zu überprüfen.

Andrey Taptunov
quelle
7

Ich denke, wenn Sie dies brauchen, haben Sie entweder eine zu lange Methode oder eine Klasse, die versucht, zu viel zu tun, oder beides.

Methoden sollten niemals länger als ein paar Codezeilen sein. Verwenden Sie eine oder zwei lokale Variablen, um zu bestimmen, was einfach wird. auch mit nur den 3 Zeilen Kontext der meisten Diff-Tools. Wenn Ihre Methoden zu lang sind und Ihre Klassen zu viele Verantwortlichkeiten haben (was häufig zu viele Felder bedeutet), besteht die Lösung darin, sie stattdessen zu teilen.

Ich denke, dass "dies" nur Code durcheinander bringt. Insbesondere bei modernen IDEs, die lokale Parameter / lokale Variablen / Felder unterschiedlich färben.

Eric-Karl
quelle
5

Ich denke, Sie haben Ihre eigene Frage damit beantwortet :

Es fühlt sich für mich natürlicher an zu schreiben

... this.foo ...

als

... foo ...

da es mir hilft, Instanzattribute von lokalen Variablen zu unterscheiden.

Wenn Sie sich this.beim Verbessern Ihrer Kenntnisse in Java wohler fühlen, sollten Sie das Ding auf jeden Fall verwenden ( ich denke, es ist in gewisser Weise das vertraute Python-Selbst , mit dem Sie sich befassen ).

Die Sache ist, dass, obwohl die Leute solide / sachdienliche Argumente über das Verwenden oder Nicht-Verwenden vorbringen this., es sich immer noch wie eine Debatte anhört, ein gegebenes Beispiel:

  • Es macht den Zweck der Variablen klar und Sie sollten den Code umschreiben, wenn nicht klar ist, was jede Variable ist.
  • this.ist überflüssig , wenn Sie Ihren ganzen Tag in der IDE verbringen vs. I Code - Reviews und Make diffs auf verschiedenen Versionen einen Komparator ohne Syntax Hervorhebung durchzuführen;
  • nicht eingeben this.Gewinne mir wichtig Millisekunden Produktivität vs. ich durch Schlüssel bezahlt bekommen gedrückt und das Hinzufügen this.ist wie eine Gehaltserhöhung: D;
  • etc etc

Aber das Fazit ist, dass es am Ende des Tages immer noch zu persönlichen Vorlieben und dem Arbeitsumfeld zurückkehrt .


quelle
5

Normalerweise Zugabe dies ist nicht erforderlich. Ich denke nicht, dass es an sich eine schlechte Praxis ist, aber eine übermäßige Verwendung davon würde wahrscheinlich in den meisten Java-Codebasen, die ich gesehen habe, als ungewöhnlich angesehen.

Ich finde es jedoch in einigen bestimmten Situationen wertvoll:

Überschreiben lokaler Parameter - Manchmal muss angegeben werden, dass Sie eine Instanzvariable anstelle eines gleichnamigen Parameters / einer lokalen Variablen verwenden möchten. Dies ist häufig in Konstruktoren der Fall, in denen der Parametername mit dem internen Namen der Instanzvariablen übereinstimmen soll, mit der er initialisiert wird, z

class MyObject {
  int value;

  public MyObject(int value) {
    this.value=value;
  }
}

Wenn Sie andere Instanzen derselben Klasse behandeln - ich glaube, dass dies den Code klarer und verständlicher macht, wenn Sie explizit angeben, auf welche Instanz der Klasse Sie sich beziehen, z

class MyObject {
  int value;
  ....

  public MyObject add(MyObject other) {
    return new MyObject( this.value + other.value )
  }
}
mikera
quelle