Die Klasse java.lang.object Thorsten Treffer 6. Dezember 2003
1 java.lang.object Die Klassenhierarchie von Java kann als Baum aufgezeichnet werden, dessen Wurzel die Klasse Object ist. Mit anderen Worten: alle Java-Klassen erben automatisch von der Klasse Object, ohne das dies explizit programmiert werden muss. Dies ist fester Bestandteil der Sprache Java. Damit besitzen auch alle Klasse automatisch die Methoden, die in der Klasse Object definiert sind, und damit eine gewissen Grundfunktionalität. Interessant sind vor allem: public String tostring() public boolean equals(object o) 2 public String tostring() Eine Klasse MeineKlasse sei gegeben. Der folgende Programmcode: public static void main(string[] args){ System.out.println("Zimtstern"); String s = new String("Kecks"); System.out.println(s); MeineKlasse meins = new MeineKlasse(); System.out.println(meins); erzeugt folgende Ausgabe: Zimtstern Kecks MeineKlasse@16930e2 Die ersten beiden Ausgaben stellen keine Überraschung dar, aber was hat die letzte zu bedeuten? Mit wenigen Worten: Die Methode public String to- String() wird aufgerufen, wenn man ein Objekt per System.out.println(Object o) auf die Konsole ausgeben möchte. Wenn man in der Klasse des auszugebenen Objektes die tostring()-methode, die sie durch Vererbung von der Klasse Object besitzt, nicht überschreibt, sie also seinen Bedürfnissen anpasst, wird der Code ausgeführt, wie er in der Klasse Object steht, der lediglich die Speicheradresse des Objektes ausgibt. Die Ausgabe MeineKlasse@16930e2 ist also die Speicheradresse der Objektes meins. Da dies in der Regel nicht sinnvoll ist, sollte man die Methode tostring() überschreiben, damit sie zum Beispiel eine Objektbeschreibung ausgibt. Bsp.: 1
public String tostring(){ //Rückgabe-String erzeugen String toreturn = new String(""); //Rückgabe-String füllen toreturn += "Beschreibung:"; toreturn += "Eigenschaft Alter:" + this.alter; toreturn += "Eigenschaft Wert:" + this.wert; //String zurückgeben return toreturn; Jetzt wird bei der Ausgabe eines Objektes dieser Klasse nicht mehr die Speicheradresse, sondern eine aussagekräftigere Objektbeschreibung ausgegeben. 3 public boolean equals(object o) Folgender Programmcode: public static void main(string[] args){ int a = 5; int b = 5; System.out.println(a == b); MeineKlasse meins = new MeineKlasse(); MeineKlasse deins = new MeineKlasse(); System.out.println(meins == deins); System.out.println(meins.equals(deins)); true false false erzeugt folgende Ausgabe: Wenn der ==-Operator aufgerufen wird, werden immer die Speicheradressen 1 der beteiligten Objekt verglichen 2. Die Methode public boolean equals(object 1 Hier sei nochmal auf den new-operator hingewiesen. Dieses Schlüsselwort sagt Java, dass es Speicherraum reservieren muss. Jedes Objekt, das mit new initialisiert wird, hat also automatisch einen eigenen Adressraum. 2 das gilt auch für die beiden int-werte. Java legt sich intern eine Speicherbank aller in eurem Code vorkommenden int-werte an. Alle 5er liegen also auf der gleichen Speicheradresse, weshalb der ==-vergleich von zwei 5en true ergibt. 2
o) aus der Klasse Object macht, wenn die nicht überschrieben wurde, nichts anderes. Wenn wir wollen, dass equals(object o) intuitivere Ergebnisse liefert, müssen wir die Methode also überschreiben und ihr dadurch eine intelligentere Funktionalität geben. Bsp.: public boolean equals(object o){ if(o instanceof MeineKlasse){ MeineKlasse tocheck = (MeineKlasse) o; return (this.alter == tocheck.alter && this.wert == tocheck.wert); else return false; Erklärung: Wir wollen zwei MeineKlasse-Objekte miteinander vergleichen, und dazu müssen wir die Methode equals(object o) überschreiben. Dazu sind wir gezwungen, die Signatur 3 der Methode exakt zu kopieren. Wir sind also gezwungen, als Parameter ein Object zu übergeben. Der Parameter der Methode ist daher von der Klasse Object. Object ist, wie gesagt, die Oberklasse aller anderen Klassen. Jede dieser Klassen besitzt die Grundfunktionalität von Object und fügt dieser lediglich Spezialisierungen hinzu. Wenn wir Java sagen, dass es diese Spezialisierungen ausblenden soll, können wir jedes Objekt behandeln, als wäre es eine Instanz der Klasse Object. Dadurch ist die Methode equals(object o) universell einsetzbar, da man als Parameter alles mitgeben kann, wozu man gerade Lust hat 4. Die Variable o ist aber eigentlich eine Instanz der Klasse MeineKlasse, da wir die Methode mit einem MeineKlasse-Objekt aufrufen, wird aber in der Methode als Object behandelt. Mit dem Schlüsselwort instanceof überprüft Java, welche Klasse sich ergibt, wenn die ausgeblendeten Spezialisierungen wieder einblendet werden. Mit instanceof MeineKlasse überprüfen wir, ob der Parameter o eine Instanz der Klasse MeineKlasse ist. Wenn nicht, kann der Parameter nicht gleich sein und wir gehen in den else-zweig, wo wir false zurückgeben. Wenn ja, blenden wir die Spezialisierungen in der nächsten Zeile wieder ein und betrachten den Paramter o als eine Instanz der Klasse MeineKlasse mit dem Variablen-Namen tocheck. Die nächste Zeile ist dann der Vergleich, der den ursprünglichen Adressraum-Vergleich ersetzt. Es wird also true zurückgegeben, wenn die beiden Objekte von ihren Werten her gleich sind, unabhängig ihrer Adressräume. 3 Die Signatur einer Methode ist der Methodenkopf zusammen mit den Parametern, hier also public boolean equals(object o). 4 Ausgenommen sind hier die primitiven Datentypen, da sie keine Objekte sind. 3
4 Nochmal in Kürze Alle Klasse erben implizit von der Klasse java.lang.object und besitzen von Beginn eine Grundfunktionalität, über deren praktischen Sinn man sich streiten kann. Die Methode public String tostring() wird immer dann aufgerufen, wenn ein Objekt per System.out.println(Object o) auf die Konsole ausgegeben wird. Durch überschreiben dieser Methode kann man selber bestimmen, welche Informationen auf der Konsole landen, wenn man mit dem Standard, nämlich der Ausgabe der Speicheradresse, nicht zufrieden ist. Die Methode public boolean equals(object o) verhält sich im Standard wie der ==-Operator, er vergleicht also die Speicheradressen der beiden zu vergleichenden Objekte. Auch hier empfiehlt es sich, die Methode zu überschreiben, wenn man Objekte auf eine andere Art miteinander vergleichen möchte. 4