Keylearnings:
- Die Bedeutung von Java
this
. - Was sind Referenzen?
- Wofür eigentlich Java
this
? - Wie du mit Hilfe von Java
this
Namenskonflikte vermeidest. - Wie du mit Hilfe des Schlüsselworts
this
einen Konstruktor aufrufst. - Wie du Java
this
als Übergabeparameter verwendest.
Es gibt Dinge, die mich verwirren.
Zum Beispiel fliegende Katzen, kleine dünne Menschen, die zwei Jumbo Pizzen verdrücken oder auch das Java Schlüsselwort this
.
Zumindest die Verwirrung um das Java this
Schlüsselwort möchte ich in diesem Artikel auflösen.
Das Schlüsselwort Java this
Um das Java this
Schlüsselwort zu verstehen, müssen wir uns zunächst nochmal darüber unterhalten was eigentlich passiert, wenn wir mittels des new
Operators ein Objekt erzeugen.
Dazu benötigen wir als erstes eine Klasse, mit der wir experimentieren können. Schauen wir uns dazu einen echten Klassiker an, nämlich eine Klasse Kraftfahrzeug
.
public class Kraftfahrzeug { public int ps = 0; private int verbrauch = 0; private int geschwindigkeit = 0; }
Die Klasse enthält die zwei privaten Attribute verbrauch
und Geschwindigkeit
und außerdem, etwas was wir im echten Leben NIEMALS machen sollten, ein öffentliches Attribut ps
.
Ziemlich nutzlos! Aber lass uns dennoch zwei Instanzen dieser Klasse erzeugen.
1: Kraftfahrzeug fahrzeug1 = new Kraftfahrzeug(); 2: Kraftfahrzeug fahrzeug2 = new Kraftfahrzeug();
Der new
Operator sorgt dafür, dass Speicher für die zu erzeugenden Objekte reserviert wird.
Nach den beiden Anweisungen von oben haben wir also zwei Speicherbereiche, in denen wir jeweils Platz für die Kraftfahrzeug Attribute ps
, verbrauch
und geschwindigkeit
haben.
Okay, geben wir beide Variablen auf dem Bildschirm aus und sehen mal nach, was deren Inhalt ist.
System.out.println(fahrzeug1); System.out.println(fahrzeug2);
Als Bildschirmausgabe erhalten wir:
Kraftfahrzeug@2a139a55 Kraftfahrzeug@15db9742
Hmm, what’s the fuck??
Was ist hier passiert? Welchen Inhalt haben die Variablen fahrzeug1
und fahrzeug2
?
Das was wir hier sehen nennt man Referenz. Eine Referenz kann man sich vorstellen wie eine Adresse, unter der wir den für ein Objekt reservierten Speicherbereich finden.
Unsere Bildschirmausgabe von oben können wir also als die Adressen der Speicherbereiche verstehen, in denen wir die Objekte fahrzeug1
und fahrzeug2
speichern.
Also Merke:
Wenn wir Objekte einer Variablen zu weisen, dann weisen wir der Variable nicht den Inhalt des Objekts zu, sondern lediglich einen Verweis auf die Position im Speicher, an der es gespeichert ist.
Schauen wir uns die Konsequenz dieser Feststellung an einem Beispiel an:
1: Kraftfahrzeug fahrzeug3 = fahrzeug1; 2: fahrzeug3.ps = 120; 3: fahrzeug1.ps = 160; 4: System.out.println(fahrzeug3.ps); 5: System.out.println(fahrzeug1.ps);
In der ersten Zeile weisen wir fahrzeug1
, einer neu erzeugten Kraftfahrzeug Variablen fahrzeug3
zu.
Anschließend weisen wir dem fahrzeug3
die PS Zahl 120 und dem fahrzeug1
die PS Zahl 160 zu und geben beide PS Zahlen auf dem Bildschirm aus.
Mit welcher Ausgabe rechnest du?
Vielleicht?
120 160
Mal sehen? Lass uns das Programm starten! Trommelwirbel!! Die Programmausgabe lautet:
160 160
Hmm, sowohl das fahrzeug1
als auch das fahrzeug3
haben 160PS. Merkst du woran es liegt?
Wir haben für fahrzeug3
keine neue Instanz mittels des new
Operators erzeugt und somit auch keinen Speicher reserviert sondern lediglich fahrzeug1
der Variablen fahrzeug3 zugewiesen.
Geben wir beide Variablen auf dem Bildschirm aus, so erhalten wir:
Kraftfahrzeug@2a139a55 Kraftfahrzeug@2a139a55
Beide Variablen zeigen also auf den gleichen Speicherbereich und ändern deshalb auch die gleichen Attribute.
Deshalb setzen wir zwar in Zeile zwei, das ps
Attribut auf 120, da wir in Zeile drei aber den gleichen Speicherbereich ansprechen wird dieser Wert sofort mit dem Wert 160 überschrieben.
Aber okay, okay wir wollten über das Java this
Schlüsselwort plaudern. Also was hat das alles mit dem Java this
Schlüsselwort zu tun?
Nun ja, das Java this
Schlüsselwort liefert auch nichts anderes als eine Referenz und zwar eine Referenz auf das Objekt, in dem wir uns befinden.
Warte! Ich zeigs dir. Lass und die Klasse von oben um eine Methode getMe
erweitern.
public class Kraftfahrzeug { private int ps = 0; private int verbrauch = 0; private int geschwindigkeit = 0; public Kraftfahrzeug getMe(){ return this; } }
Der Rückgabewert der Methode getMe
ist vom Typ Kraftfahrzeug, d.h. die Methode ist in der Lage eine Referenz auf einen Speicherplatz, in dem ein Kraftfahrzeug gespeichert ist zurück zuliefern.
Im Methodenrumpf wird lediglich die this
Referenz über ein return
zurückgegeben.
Und halt dich fest, hier die Auflösung des Geheimnisses um das Schlüsselwort this
.
Das Schlüsselwort this liefert eine Referenz auf den Speicherbereich, in dem ein Objekt gespeichert ist zurück.
Sehen wir uns auch das anhand eines Beispielprogramms an.
1: System.out.println(fahrzeug1); 2: System.out.println(fahrzeug1.getMe());
Welche Ausgabe erwartest du?
In der ersten Zeile geben wir die Referenz auf den Speicherbereich, in dem das Objekt fahrzeug1
gespeichert ist aus.
Und in der zweiten Zeile?
Ebenso! Nur das wir hier die Referenz mit Hilfe des this
Schlüsselwortes in der getMe()
Methode zurückliefern.
Hier zum Beweis die Bildschirmausgabe.
Kraftfahrzeug@2a139a55 Kraftfahrzeug@2a139a55
Anwendungen des Java this Schlüsselwortes
Soweit so gut! Aber wofür können wir das jetzt gebrauchen?
Java this zum Auflösen von Namenskonflikten
Das erste und berühmteste Anwendungsgebiet von java this
ist das Auflösen von Namenskonflikten insbesondere bei Konstruktoren und setter Methoden.
Hier zunächst ein Beispiel einer setter Methode, so wie es NICHT funktioniert.
1: public void setGeschwindigkeit(int geschwindigkeit) { 2: geschwindigkeit = geschwindigkeit; 3:}
Die Methode besitzt einen Integer-Parameter mit dem Namen geschwindigkeit
. Und genau das ist ein Problem!
In der Klasse Kraftfahrzeug
gibt es nämlich ebenfalls ein Attribut mit dem Namen geschwindigkeit
, dem wir über unsere setter Methode einen Wert zu weisen wollen.
Innerhalb von setGeschwindigkeit
ist aber nur der Übergabeparameter mit dem Namen geschwindigkeit
bekannt. Wie greifen wir also aus der setter-Methode auf das Attribut geschwindigkeit
zu?
Es wird dich überraschen. Die Lösung ist Java this!
Wir müssen die zweite Zeile entsprechend anpassen.
1: public void setGeschwindigkeit(int geschwindigkeit) { 2: this.geschwindigkeit = geschwindigkeit; 3:}
Jetzt wird der Wert des Übergabeparameters geschwindigkeit
dem Attribut geschwindigkeit
zu gewiesen.
Java this zum Aufruf von Methoden und Konstruktoren
Ein weiterer Fall, bei dem wir das Schlüsselwort this
verwenden ist der Aufruf überschriebener Konstruktoren.
Bis jetzt haben wir in unserer Kraftfahrzeug
Klasse noch keinen Konstruktor implementiert, was dazu führt, dass alle Attribute nach Erzeugung eines Objektes den Wert 0 haben.
Holen wir das nach und versehen unsere Klasse zum einen mit einem Standard-Konstruktor und zum anderen mit einem Konstruktor, mit dem wir die Attribute ps
, geschwindigkeit
und verbrauch
initialisieren können.
Beginnen wir mit dem wenig spektakulärem Standard-Konstruktor.
public Kraftfahrzeug(){}
Und als nächstes der Konstruktor um die Attribute zu initialisieren.
public Kraftfahrzeug(int ps, int verbrauch, int geschwindigkeit) { this.ps = ps; this.verbrauch = verbrauch; this.geschwindigkeit = geschwindigkeit; }
Um Namenskonflikte zwischen der Parameterliste des Konstruktors und den Attributen der Klasse zu vermeiden, haben wir auch hier wieder das Schlüsselwort this
verwendet.
Mit Hilfe des neuen Konstruktors haben wir jetzt die Möglichkeit Fahrzeug-Objekte mit initialisierten Attributen zu erzeugen.
Kraftfahrzeug fahrzeug = new Kraftfahrzeug(80,6,240);
Hiermit haben wir ein Kraftfahrzeug mit 80PS, 6Liter Verbrauch und einer Höchstgeschwindigkeit von 240 erzeugt.
Eine andere Möglichkeit die Attribute zu initialisieren liefert das this Schlüsselwort.
Mit Hilfe von this können wir den Konstruktor Kraftfahrzeug(int ps, int verbrauch, int Geschwindigkeit)
aus dem Standardkonstruktor heraus aufrufen.
Dazu müssen wir den Standardkonstruktor um einen this
Aufruf wie folgt erweitern.
public Kraftfahrzeug(){ this(80,6,240); }
Nach dieser Änderung wird mit der Anweisung
Kraftfahrzeug fahrzeug = new Kraftfahrzeug();
ein Kraftfahrzeug mit 80PS, 6Liter Verbrauch und einer Höchstgeschwindigkeit von 240 erzeugt.
Die Anweisung this(80,6,240)
sucht in der Klasse nach einem Konsruktor mit drei Parametern und ruft diesen mit den entsprechenden Argumenten auf.
In unserem Fall wird also der Konstruktor Kraftfahrzeug
mit den Argumenten 80,6 und 240 aufgerufen.
Java this als Argument einer Methode
Eine weitere Verwendung von Java this
ist die Übergabe als Parameter an eine Methode.
Welchen Sinn macht das?
Kreieren wir zur Demonstration eine Klasse Waschanlage
mit einer Methode fahrzeugWaschen
.
class Waschanlage { public void fahrzeugWaschen(Kraftfahrzeug fahrzeug){ //Methode fahrzeugWaschen } }
Mit Implementierungs-Details der Methode fahrzeugWaschen
müssen wir uns an dieser stelle nicht beschäftigen.
Unser Ziel ist im folgenden die Klasse Kraftfahrzeug
um eine Methode waschen
zu erweitern, welche die Methode fahrzeugWaschen
aus der Klasse Waschanlage aufruft.
Folgendes soll also möglich sein:
Kraftfahrzeug fahrzeug = new Kraftfahrzeug(); fahrzeug.waschen();
Wie ist die waschen
Methode zu implementieren?
Wir wollen genau das Kraftfahrzeug waschen, aus dem wir die Methode heraus aufrufen, daher müssen wir auch eine Referenz auf genau dieses Kraftfahrzeug an die Methode fahrzeugWaschen
übergeben.
Und jetzt rate mal, wie wir das hinbekommen? Right! Mit Java this
. Lass uns die Klasse Kraftfahrzeug um die Methode waschen
erweitern.
public void waschen(){ 1: Waschanlage waschAnlage = new Waschanlage(); 2: waschAnlage.fahrzeugWaschen(this); e: }
Da wir unser Kraftfahrzeug in einer Waschanlage waschen wollen, legen wir zunächst in Zeile Eins die Instanz einer Waschanlage an.
Als nächstes rufen wir dann in Zeile Zwei die in der Waschanlage implementierte Methode fahrzeugWaschen
auf, die als Übergabeparameter eine Referenz auf ein Kraftfahrzeug
Objekt erwartet.
Diese Referenz soll auf das Objekt zeigen, aus dem wir die Methode fahrzeugWaschen
heraus aufrufen. Und genau das liefert das Schlüsselwort this
.
Noch nicht klar? Okay, implementieren wir die gleiche Funktionalität erneut, aber ohne das Schlüsselwort this
.
1: Kraftfahrzeug fahrzeug = new Kraftfahrzeug(); 2: Waschanlage anlage = new Waschanlage(); 3: anlage.fahrzeugWaschen(fahrzeug);
Dieser Code liefert das gleiche Ergebnis wie der Aufruf von
fahrzeug.waschen();
Warum das??
Weil die Referenz, die in der Variable fahrzeug
gespeichert ist, die selbe ist, die wir in der Methode waschen
aus der Klasse Kraftfahrzeug, über das this
Schlüsselwort an die Methode fahrzeugWaschen
aus der Klasse Waschanlage
übergeben.
Ich hoffe ich konnte in diesem Artikel die Verwirrung um das java Schlüsselwort ein wenig mildern. Merke dir einfach: Dass Schlüsselwort this liefert eine Referenz auf das Objekt, in dem du dich befindest zurück.
Ich freue mich auf deine Fragen im Kommentarbereich.
Hat dir der Artikel gefallen? Dann folge uns am besten gleich auf Facebook!
jakob
12. Februar 2017 at 11:23nice geschrieben
hat mir sehr weitergeholfen danke
Kim Peter
13. Februar 2017 at 6:42Hi Jakob, Danke für dein Feedback. Freue mich wenn ich weiterhelfen kann. Viele Grüße Kim
Kristin
25. März 2017 at 9:06Super erklärt! Hab das wort ‚this‘ echt gehasst. Vielen Dank!
Kim Peter
25. März 2017 at 15:07Hi Kristin, sehr gerne! Viele Grüße Kim
Adi
12. Mai 2017 at 16:39Super gemacht Kim. Hat geholfen. Danke.
Kim Peter
14. Mai 2017 at 11:56Danke dir!
Dominic
26. Mai 2017 at 7:46Wow, ich muss sagen mir hat das sehr geholfen, verständlich erklärt und mit guten Beispielen ergänzt. Ein grosses Lob an dich Kim!!!
Kim Peter
28. Mai 2017 at 7:47Vielen Dank Dominic!
Robert
25. Juli 2017 at 9:33Hallo,
danke für den Artikel!
Ist Kim nicht ein Frauenname?
Kim Peter
25. Juli 2017 at 10:33Hallo Robert,gerne! Nein, es ist beides. Allerdings habe ich deshalb als Zweit-Namen Peter. Viele Grüße Kim
Carsten
29. August 2017 at 19:50Super erklärt. Besten Dank!!!!
Kim Peter
30. August 2017 at 15:01sehr gerne!
Marc B
16. Oktober 2017 at 19:11Danke Kim, leicht und verständlich, hat mich abgeholt, Klasse !!!
Kim Peter
17. Oktober 2017 at 5:42Viele Dank! Ich freue mich sehr über deine Rückmeldung.
Milena
25. Oktober 2017 at 20:09Hey Kim,
sehr guter Artikel! Dank dir ist mir jetzt endlich klar, wofür this zu gebrauchen ist 🙂
Kim Peter
6. November 2017 at 6:31Vielen Dank!
AndyND
2. November 2017 at 20:17Super erklärt. Genial verständliche Beispiele. Vielen vielen Dank.
Kim Peter
6. November 2017 at 6:29Vielen Dank!
Paul
20. November 2017 at 18:03Super hilfreich, aber 240 mit 80 PS ist etwas zu optimistisch ;D
Kim Peter
25. November 2017 at 18:14Hallo Paul, ich kenne mich da leider nicht so gut. Ich besitze kein Auto 😉 Viele Grüße Kim
Can
23. November 2017 at 14:15top geschrieben und sehr strukturiert erklärt
Kim Peter
25. November 2017 at 18:12Dankeschön!
Olaf
8. Dezember 2017 at 8:19Hallo, ich bin nicht gerade ein OOP Freak, und die Notwendigkeit von „this“ habe ich trotzdem nicht verstanden. Aber Du hast eine gute Art, die Dinge rüberzubringen.
Kim Peter
27. Januar 2018 at 8:58Ich danke dir!
Olaf
8. Dezember 2017 at 8:32Trotzdem eine Kritik an der Nutzung von „this“ aber nicht an Dir,
Beispiel:
public void setGeschwindigkeit(int Geschwindigkeit) {
Geschindigkeit = Geschwindigeit;
}
Der Compiler hat alle Informationen, um trotz der ungeschickten Wahl der Variablennamen damit umzugehen: Der Compiler weiß, dass der Übergabeparameter „Geschwindigkeit“ einen Wert enthält, aber innerhalb der Funktion nicht gesetzt werden kann. Daraus hätte er folgern können, dass der Parameter „Geschindigkeit“ nur rechts
Geschwindigkeit = Geschwindigkeit;
stehen kann. Für die Einführung von „this“ gibt es jedenfalls hier keinen Grund.
PS ich stehe der ganzen OOP skeptisch gegenüber. Habe mehrere Bücher darüber gelesen und leider mit C++ angefangen.
Kim Peter
27. Januar 2018 at 9:02Hallo Olaf, guter Einwand! Erst wenn eine gleichnamige Variabel innerhalb der Methode definiert würde, hätte man ein Problem. C++ ist super! Meiner Meinung nach aber auch deutlich komplizierter als Java und auch als die meisten anderen Sprachen (mit Ausnahme Assembler). Viele Grüße Kim
Olaf
8. Dezember 2017 at 9:01Im restlichen Code mit „this“ hatte ich das Problem zu erahnen, in welcher Relation es steht. Befinde ich mich direkt unter main() oder bin ich in einer anderen Klasse. Wer ruft wen von welchem Ort aus auf, das ist mir nicht klar geworden.
und Codezeilen wie
Waschanlage waschAnlage = new Waschanlage();
in denen das Wort Waschanlage drei mal vorkommt, machen solchen Code nicht gerade verständlich, aber das scheint wohl ein generelles OO-Problem zu sein.
Der letzte Satz hat es dann aber wieder gebracht:
Das Schlüsselwort „this“ liefert eine Referenz auf das Objekt, in dem Du Dich befindest.
Jetzt wo ich es schreibe, wird es wieder unklar. Wenn ich nicht weiß, wo ich mich befinde, dann muß ich im Sourcecode nachsehen, wo mein Cursor gerade blinkt. Ich denke, dass das nicht gemeint war.
Gemeint ist möglicherweise:
Mein Rechner arbeit Code ab und befindet sich im Objekt A und ruft eine Methode aus Objekt B auf. Dabei verwendet er als Übergabeparameter this, d.h. Objekt B.Methode(this). Dann weiß Methode(this) durch this, was sie bearbeiten soll, weil this eine Referenz auf das Objekt ist, das bearbeitet werden soll.
oder so ähnlich. OOP ist echt, ähm, vorsichtig ausgedrückt: gewöhnungsbedürftig.
Resumee für mich und nur für mich: this nicht verwenden, wenn Du nicht wirklich verstanden hast, wie es funktioniert.
Habt Ihr denn keine Probleme damit?
Kim Peter
27. Januar 2018 at 8:58Hallo Olaf, vielen Dank für deinen Kommentar. Und sorry für meine späte Antwort (WordPress hat den Kommentar irgendwie in den falschen Ordner gepackt). OOP macht sinn, da es ein Werkzeug ist um Komplexität zu verbergen. Um einen Motor zu verwenden, brauchst du nicht unbedingt genau zu wissen wie dieser tatsächlich funktioniert. Das ist beispielsweise in der prozeduralen Welt anders. Aber du hast trotzdem völlig recht OOP ist definitiv nicht die Lösung für alles. Nicht umsonst wurde in Java 8 und insbesondere Java 9 funktionale Elemente in die Sprache aufgenommen. Viele Grüße Kim
Jesaja
17. Januar 2018 at 11:26Als nächstes rufen wir dann in Zeile Zwei die in der Waschanlage implementierte Methode waschen auf, die als Übergabeparameter eine Referenz auf ein Kraftfahrzeug Objekt erwartet.
Müsste es nicht heißen:
Als nächstes rufen wir dann in Zeile Zwei die in der Waschanlage implementierte Methode fahrzeugWaschen auf, die als Übergabeparameter eine Referenz auf ein Kraftfahrzeug Objekt erwartet.
Kim Peter
17. Januar 2018 at 12:07Hallo Jesaja, absolut richtig! Habe es geändert. Viele Grüße Kim
Fina
28. März 2018 at 22:59Genau das was ich gesucht habe und so einfach erklärt. Danke Dir!
Kim Peter
8. April 2018 at 17:28Super!
Arne
8. Januar 2019 at 10:02Hallo Kim,
als erfahrener Programmierer habe diesen Artikel sehr genau gelesen und ich muss echt sagen, dass ich diesen sehr gut finde. Er ist sehr verständlich und einfach zu lesen.
Keep it up
MFG
Arne
Kim Peter
8. Januar 2019 at 11:55Hallo Arne, ich danke dir vielmals. Viele Grüße Kim
pablo
17. Januar 2019 at 13:15MEGAAA Danke
Kim Peter
17. Januar 2019 at 13:21Hallo Pablo, gerne! Viele Grüße Kim
Hermann
29. Januar 2019 at 9:12Moin Kim,
super Artikel, toll zu lesen, rundum einfach Weltklasse mein lieber!!!
Informativ und verständlich
Kim Peter
9. Februar 2019 at 19:41Hallo Hermann, ich danke dir! Viele Grüße Kim
Jamie
26. Februar 2019 at 21:42Danke, deine Seite ist super und sehr verständlich…bei vielen Fragen habe ich mich halb zu Tode gesucht, aber bei deiner Seite ist alles klar und logisch. TOP 🙂
Kim Peter
27. Februar 2019 at 7:35Hallo Jamie, freue mich, wenn du die Antworten auf deine Fragen gefunden hast. Viele Grüße Kim
Nils
7. März 2019 at 14:07Vielen Dank für diese umfangreiche, gut strukturierte und vorallem gut vorstellbare Erklärung dank der gegebenen Beispiele!
Kim Peter
8. März 2019 at 11:19Hallo Nils, danke dir für das Feedback! Viele Grüße Kim
Timo
21. März 2019 at 9:41Mega Artikel nur verwirrt mich die Stelle in Zeile 56 etwas da blick ich nicht ganz durch, ich bitte um nähere Erläuterung
Kim Peter
2. April 2019 at 7:37Was genau meinst du?
Timo
26. März 2019 at 9:03Moin Kim,
der Artikel hat mir wahnsinnig geholfen für meine Hausarbeit. Endlich hab ich java this verstanden, sehr gut erklärt und ein sehr hilfreicher Artikel.
Ya Hero Ya Mero
Grüße Timo
Kim Peter
2. April 2019 at 7:35Hallo Timo, danke für dir Rückmeldung. Freue mich wenn ich helfen konnte. Viele Grüße Kim
Tina
2. Januar 2020 at 15:26Hi Kim,
deine Erklärungen sind immer super hilfreich! Vielen Dank dafür!! Und ich mag deinen Schreibstil! Das lässt sich so schön „leicht und locker“ lesen 🙂
Kim Peter
19. Mai 2020 at 18:36Hallo Tina, vielen Dank! Viele Grüße Kim
Thomas
22. Januar 2020 at 16:43Vielen Dank, hat mir sehr geholfen!
Kim Peter
5. Februar 2020 at 8:24Hallo Thomas, das freut mich sehr! Viele Grüße Kim
Lenny
7. April 2020 at 9:10Hey, toller Artikel, leicht und verständlich erklärt. Frage: Wieso kommen keine neuen Artikel? Ich persönlich finde deine Artikel sehr Hilfreich & verständlich geschrieben.
Danke & bleibe gesund!
Kim Peter
18. April 2020 at 19:02Hallo Lenny, danke dir ich hoffe ich finde demnächst wieder mehr Zeit für den Blog. Viele Grüße Kim
Choose a style: