equals()-Methode Verständnis Frage anhand Code Beispiel

NeoLexx

Mitglied
Hallo Leute, wer kann mir kurz folgendes erklären?

Java:
public class Kunde {
    private int kundennummer;
    private String name;
    private String vorname;
    private String geschlecht;

    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj instanceof Kunde) {
            Kunde k = (Kunde) obj;
            return kundennummer == k.kundennummer;
        }
        else 
            return super.equals(obj);
        
        }
    }

Ich habe mehrere Fragen, aber vielleicht erkläre ich erstmal was ich verstehe:

equals()-Methode ist eine Methode der Oberklasse aller Klassen mit dem Namen Object.

Sie wird hier ab Zeile 7 überschrieben.

In Zeile 8 wird geprüft ob das übergeben Objekt obj, das gleiche ist wie die Instanz von Kunde, die diese Methode aufruft. Falls ja, dann wird true ausgegeben.

In Zeile 9 wird eine bedingte Anweisung erzeugt, falls obj und Kunde von gleichen Typ sind, dann wird in Zeile 10 ein Variable k von Typ Kunde erzeugt, auf die dann obj gecastet wird.
An dieser Stelle verstehe ich nicht genau was damit bewirkt wird, denn man hat doch vorher schon geprüft ob obj vom Typ Kunde ist, warum muss es jetzt nochmals auf Kunde gecastet werden. Bei der Gelegenheit, vielleicht kann mir einer genau erklären was bedeutet es, wenn ich auf ein bestimmten Typ caste?

In Zeile 11 werden nun, mittels Gleichheitsoperator, die beiden Werte, der Variablen von der aufrufenden Instanz und der vergleichenden Instanz, verglichen. Sind sie identisch so wird ture ausgegeben, andernfalls false.

Dann, in Zeile 14, wird, sofern die Bedingung aus der bedingten Anweisung aus Zeile 9 false ist, das ganze an die equals()-Methode der Klasse Object übergeben. Und an dieser Stelle verstehe ich nicht wieso das noch getan werden muss. Denn immerhin haben wir nun als Parameter, ein nicht Kompatiblies Objekt zur Instanz der Klasse Kunde angegeben, wieso geben wir nach else nicht einfach ein return false aus?
 
B

BestGoalkeeper

Gast
Hier ist das etwas verkürzt
Java:
public class Kunde {
    private int kundennummer;
    private String unwichtig;
    public Kunde(int kundennummer, String unwichtig) {
        Objects.requireNonNull(unwichtig);
        this.kundennummer = kundennummer;
        this.unwichtig = unwichtig;
    }
    @Override
    public int hashCode() {
        return Objects.hash(kundennummer);
    }
    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof Kunde)
            return kundennummer == ((Kunde) obj).kundennummer;
        return super.equals(obj);
    }
}
 

LimDul

Top Contributor
Wo ist der null check? ;)
Braucht man nicht, da instanceof nur bei non null Objekten true liefert.

Hallo Leute, wer kann mir kurz folgendes erklären?


In Zeile 9 wird eine bedingte Anweisung erzeugt, falls obj und Kunde von gleichen Typ sind, dann wird in Zeile 10 ein Variable k von Typ Kunde erzeugt, auf die dann obj gecastet wird.
An dieser Stelle verstehe ich nicht genau was damit bewirkt wird, denn man hat doch vorher schon geprüft ob obj vom Typ Kunde ist, warum muss es jetzt nochmals auf Kunde gecastet werden. Bei der Gelegenheit, vielleicht kann mir einer genau erklären was bedeutet es, wenn ich auf ein bestimmten Typ caste?
Nun, du möchtest auf das Attribut kundennummer zugreifen. Das gibt es aber nicht in der Klasse Object - sondern nur in der Klasse Kunde. Also musstest du das Objekt auf den Typ casten um auf das Attribut zugreifen zu können.
In Zeile 11 werden nun, mittels Gleichheitsoperator, die beiden Werte, der Variablen von der aufrufenden Instanz und der vergleichenden Instanz, verglichen. Sind sie identisch so wird ture ausgegeben, andernfalls false.
Korrekt.

Dann, in Zeile 14, wird, sofern die Bedingung aus der bedingten Anweisung aus Zeile 9 false ist, das ganze an die equals()-Methode der Klasse Object übergeben. Und an dieser Stelle verstehe ich nicht wieso das noch getan werden muss. Denn immerhin haben wir nun als Parameter, ein nicht Kompatiblies Objekt zur Instanz der Klasse Kunde angegeben, wieso geben wir nach else nicht einfach ein return false aus?
Weil der Programmierer es unnötig komplex machen wollte. Wenn du dir den Code von Object.equals ansiehst:
Java:
    public boolean equals(Object obj) {
        return (this == obj);
    }
Dann wäre ein return false; an der Stelle auch vollkommen ausreichend.
 

NeoLexx

Mitglied
Super danke für die schnellen Antworten. 👍

Hier ist das etwas verkürzt
Java:
public class Kunde {
    private int kundennummer;
    private String unwichtig;
    public Kunde(int kundennummer, String unwichtig) {
        Objects.requireNonNull(unwichtig);
        this.kundennummer = kundennummer;
        this.unwichtig = unwichtig;
    }
    @Override
    public int hashCode() {
        return Objects.hash(kundennummer);
    }
    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof Kunde)
            return kundennummer == ((Kunde) obj).kundennummer;
        return super.equals(obj);
    }
}
Danke für deine verkürzte Variante, aber mir ging es darum den Code den ich im Script so übergeben bekommen hatte zu verstehen.
Dann wäre ein return false; an der Stelle auch vollkommen ausreichend.
Echt jetzt? Das machen die doch mit Absicht! Aber vielleicht besser so, so wird man dann doch gezwungen etwas genauer nachzudenken 🙄.
Nun, du möchtest auf das Attribut kundennummer zugreifen. Das gibt es aber nicht in der Klasse Object - sondern nur in der Klasse Kunde. Also musstest du das Objekt auf den Typ casten um auf das Attribut zugreifen zu können.
Wir das Casten noch in anderen Situationen benötigt, außer in der wo man eine Methode einer Unterklasse aufrufen möchte die nicht in der Oberklasse vorkommt?
 

LimDul

Top Contributor
Wir das Casten noch in anderen Situationen benötigt, außer in der wo man eine Methode einer Unterklasse aufrufen möchte die nicht in der Oberklasse vorkommt?
Immer dann, wenn du auf Eigenschaften (Felder, Methoden) einer Unterklasse zugreifen willst. Im Idealfall vermeidet man Casten soweit es geht, weil das ein Hinweis auf eine schlechte Architektur sein kann. Denn wozu nutze ich Objekte einer Oberklasse, wenn ich dann doch wieder auf die Unterklasse casten muss.

Vermeiden kann man es aber nie, insbesondere bei so Dingen wie equals, die zum einen aus einer Zeit vor den Generics stammen und die zum anderen auch sehr flexibel sein sollen.
 

NeoLexx

Mitglied
Weil der Programmierer es unnötig komplex machen wollte. Wenn du dir den Code von Object.equals ansiehst:
Java:
    public boolean equals(Object obj) {
        return (this == obj);
    }
Dann wäre ein return false; an der Stelle auch vollkommen ausreichend.
Wobei ein Frage hätte ich dann doch noch dazu. Wenn ich also zum Schluss auf die Methode der Oberklasse zugreife und dort per == prüfen lasse ob this == obj ist, bezieht sich das "this" doch dann auf die Instanz von Object oder nicht (wobei welche Instanz, habe doch keine erzeugt)? Und sagen wir mal ich würde nun als Object obj tatsächlich eine Instanz von Object übergeben, dann würde doch letztendlich ein true bekommen, oder etwa nicht?
 
B

BestGoalkeeper

Gast
der statische Typ von this ist Object, der dynamische Typ (der ja letztendlich zählt) ist Kunde
 

NeoLexx

Mitglied
der statische Typ von this ist Object, der dynamische Typ (der ja letztendlich zählt) ist Kunde
Dir ist aber schon klar, dass ich mich bei meiner Frage auf Zeile 14 des Codes beziehe?

Java:
public class Kunde {
    private int kundennummer;
    private String name;
    private String vorname;
    private String geschlecht;

    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj instanceof Kunde) {
            Kunde k = (Kunde) obj;
            return kundennummer == k.kundennummer;
        }
        else
            return super.equals(obj);
       
        }
    }
Und dass ich bei der Fragestellung von dem Szenario ausgehe, dass ich der Methode eine Objekt des Typs Object zur Prüfung übergebe?
 
Zuletzt bearbeitet:
B

BestGoalkeeper

Gast
ja stimmt ;)
Man könnte noch etwas genauer sein... der statische Typ von this ist zum Übersetzungszeitpunkt Object und der dynamische Typ von this ist in diesem konkreten Fall zur Laufzeit Kunde.
Also trifft auf das Kunde-Objekt folgendes zu, wenn super.equals darauf aufgerufen wird: a widening (assignment) reference conversion
 
B

BestGoalkeeper

Gast
dass ich der Methode eine Objekt des Typs Object zur Prüfung übergebe?
Der Typ von obj bleibt immer gleich, diesen castest du ja nicht...

Das problematische an meiner equals Methode ist nur, dass eine Kunde-erweiternde Klasse ebenfalls gleich sein kann zur Klasse Kunde und das manchmal nicht gewollt ist:
Java:
    public static void main(String[] args) {
        CD cd1 = new CD(2);
        AB cd2 = new AB(2);
        CD cd3 = new CD(3);
        System.out.println(cd1.equals(cd2));
        System.out.println(cd2.equals(cd1));
        System.out.println(cd3.equals(cd1));
        System.out.println(cd1.equals(cd3));
    }
}

class AB {
    private int id;

    public AB(int id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        return id;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof AB)
            return id == ((AB) obj).id;
        return this == obj;
    }
}

class CD extends AB {
    public CD(int id) {
        super(id);
    }
}
 

NeoLexx

Mitglied
Ich muss nochmal Fragen, da ich glaube dass meine Frage nicht ganz angekommen ist. Folgender Code ist gegeben:
Java:
public class Kunde {
    private int kundennummer;

public Kunde (int kundennnummer) {
this.kundennummer=kundennumer;
}
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj instanceof Kunde) {
            Kunde k = (Kunde) obj;
            return kundennummer == k.kundennummer;
        }
        else
            return super.equals(obj);
     
        }
    }

In einer anderen Klasse mach ich nun folgendes:

Java:
public class irgendEineKlasse{
    Kunde kd1 = new Kunde(1);
    Object ob1 = new Object();
    boolean wert = kd1.equals(ob1);
 
}

Dann bekomme ich doch ein true raus, oder nicht?

Edit:
Und zwar erst wenn das Ganze in Zeile 14 an die Oberklasse Object weiter gereicht wurde.
 
Zuletzt bearbeitet:

LimDul

Top Contributor
Nein, da kommt false raus. Was durch den Super-Aufruf am Ende zurückgegeben wird ist im Endeffekt

kd1 == obj - was wiederrum false ist.
 

NeoLexx

Mitglied
Nein, da kommt false raus. Was durch den Super-Aufruf am Ende zurückgegeben wird ist im Endeffekt

kd1 == obj - was wiederrum false ist.
Okay, danke für die konstruktive Antwort.

Das Scirpt anhand dessen ich mich gerade durcharbeite, gibt das nicht her, worauf sich das "this" aus der equals()-Methode der Oberklasse Object bezieht. Intuitiv wäre meine Vermutung, dass es sich auf die Oberklasse selbst bezieht und ich damit ein Object == obj prüfe und damit auch ein true erhalte. Immerhin, falls man in einer Mehtode this.variable benutzt, bezieht es sich auf eine Instanzvariable, daher auch erstmal meine Annahme, dass es sich auf die Klasse bezieht, die diese Methode implementiert hat.

Aber das Kapitel werde ich erstmal ruhen lassen und mich weiter an die Vorgehensweise des Skriptes halten. Eventuell wird darauf in kürze ja eingegangen.



Danke nochmal

Edit: Wobei ich gerade sehe, dass der Vergleichsoperator im Bezug auf Komplexe Datentypen immer zwei Objekte vergleicht und in dem Fall existieren ja nur diese zwei Objekte.
 
Zuletzt bearbeitet:

LimDul

Top Contributor
this heißt immer dieses Objekt.

Das heißt es bezieht sich nicht auf die Klasse, sondern die konkrete Instanz. Du kannst this (im Prinzip) auch nur innerhalb einer Instanz-Methode nutzen.

Beispiel
Java:
public class MyClass {
   public int variable;

  public void macheWas() {
    System.out.println(this.variable);
  }
}

// ...
Irgendwo anders
MyClass myObject = new MyClass();
myObject.variable = 2;
myObjkect.macheWas();
Das gibt den Wert 2 aus.

Wie du siehst, kann man auf Member Variablen eines Objektes mittels name.variable zugreifen.
Wenn du aber innerhalb eines Objektes bist (in der Methode macheWas), kannst du entweder den Namen vor dem Punkt weglassen. Oder - um dich auf das konkrete Objekt zu beziehen, in desen Methode du gerade bist - this davorstellen.
 

NeoLexx

Mitglied
Java:
public class Kunde {
  private int kundennummer;

public Kunde (int kundennnummer) {
  this.kundennummer=kundennumer;
}
public boolean equals(Object obj) {
  if (this == obj) return true;
  if (obj instanceof Kunde) {
   Kunde k = (Kunde) obj;
   return kundennummer == k.kundennummer;
  }
  else
  return super.equals(obj);

  }
}

//andere Klasse
public class irgendEineKlasse{
  Kunde kd1 = new Kunde(1);
  Object ob1 = new Object();
  boolean wert = kd1.equals(ob1);
}
//die Klasse Object, die Große, Vater und Mutter aller anderen Klassen XD

public class object{
....

public equals(Object obj) {
  return (this == obj);
Wie du siehst, kann man auf Member Variablen eines Objektes mittels name.variable zugreifen.
Wenn du aber innerhalb eines Objektes bist (in der Methode macheWas), kannst du entweder den Namen vor dem Punkt weglassen. Oder - um dich auf das konkrete Objekt zu beziehen, in desen Methode du gerade bist - this davorstellen.
Ja, das habe ich auch geblickt, denn das "this" kommt ja in der von dir beschriebenen Funktion, in der überschriebenen equals()-Methode von Kunde vor.
Wenn ich später in der Klasse "irgendEineKlasse" diese equals()-Methode aufrufe (Zeile 23) dann wird kd1 und obj mittels == verglichen, da "this" hier auf die Klasse Kunde verweist. Hab ich auch verstanden.

Wenn ich dann aber das Ganze in Zeile 14 an die equals()-Methode der Oberklasse schicke, dann bezieht sich das "this" (Zeile 31) der equals()-Methode der Oberklasse (hier Object), immer noch auf kd1. Verweist also nicht auf die Klasse Obejct, ähnlich wie es das in der Klasse Kunde tut.

Aber das wird was mit den statischen und dynamischen Typen zu tun haben, die BestGoakkeeper bereits ansprach, ein Thema mit dem ich mich zu gegebenen Zeitpunkt auseinander setzen werde, zumal es, wie bereits gesagt, bisher im Skript nicht Thematisiert worden ist.
 

NeoLexx

Mitglied
Ja, sorry. Sich über Programmiersprachen verbal auszutauschen, Bedarf höchster sprachlicher Präzision, daran muss man sich erstmals gewöhnen. Bis dahin werde ich wohl, sofern andere Fragen aufkommen werden, mehrmals Formulieren müssen. Aber ich gebe mein bestes mich verständlicher auszudrücken.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Equals-Methode überschreiben bei composition Java Basics - Anfänger-Themen 20
C Long value an Stringbuilder übergeben, equals Methode funktioniert nicht Java Basics - Anfänger-Themen 2
J compareTo()- und equals-Methode Java Basics - Anfänger-Themen 3
G Java equals() Methode Java Basics - Anfänger-Themen 9
O equals Methode möglichst effizient Java Basics - Anfänger-Themen 13
H equals methode Java Basics - Anfänger-Themen 1
L Logistiksystem Methode equals und hashcode Java Basics - Anfänger-Themen 20
J Methoden Equals Methode für Integer und Objekte überschreiben? Java Basics - Anfänger-Themen 9
H equals Methode Java Basics - Anfänger-Themen 1
S equals Methode bei String Java Basics - Anfänger-Themen 5
K Vererbung equals-Methode bei Vererbung abstrakter Klassen Java Basics - Anfänger-Themen 8
SexyPenny90 Wieso ist diese eigene Equals-Methode schlecht? Java Basics - Anfänger-Themen 17
E Equals-Methode auf Class-Object Java Basics - Anfänger-Themen 17
J Methode equals() Java Basics - Anfänger-Themen 7
D Eigene equals methode schreiben Java Basics - Anfänger-Themen 4
A veränderbar kanonische Klassen: Methode equals, hashcode, serializable Java Basics - Anfänger-Themen 5
C 2 Objekte (mathematisch) vergleichen in der equals Methode Java Basics - Anfänger-Themen 10
C hilfe bei equals Methode - es geht ums Bestehen Java Basics - Anfänger-Themen 7
G equals-Methode Java Basics - Anfänger-Themen 4
Say Equals Java Basics - Anfänger-Themen 6
W LocalDate vergleichen mit Equals? Java Basics - Anfänger-Themen 7
W Wann und warum hashcode und equals? Java Basics - Anfänger-Themen 14
X Datentypen String.equals funktioniert nicht Java Basics - Anfänger-Themen 5
S 2 Strings mit Equals vergleichen Java Basics - Anfänger-Themen 11
lallmichnichtzu Methoden Überladen des .equals-Operators Java Basics - Anfänger-Themen 6
C Objekt1.equals(Objekt2) = immer false. Wieso? Java Basics - Anfänger-Themen 22
M Objekte mittels equals vergleichen Java Basics - Anfänger-Themen 14
S Interface Equals und hashCode Java Basics - Anfänger-Themen 16
J equals funktioniert nicht - Warum Java Basics - Anfänger-Themen 13
B Date - Vergleich (equals / after) ? Java Basics - Anfänger-Themen 3
G Ratlosigkeit zur Aufgabe im Anhang (boolean, equals.) Java Basics - Anfänger-Themen 20
D Unterschied == und equals in Arrays Java Basics - Anfänger-Themen 2
M Erste Schritte Mehrere eingaben in einer Line vergleichen (if equals...) Java Basics - Anfänger-Themen 6
I equals (Override) mit eigener Exception (keine Runtime-Exception) Java Basics - Anfänger-Themen 9
A OOP Richtige Verwendung von ArrayList und equals Java Basics - Anfänger-Themen 24
E equals Prüfung fehlgeschlagen Java Basics - Anfänger-Themen 3
C Objekt equals Java Basics - Anfänger-Themen 2
L String überprüfen mit .equals .contains oder .matches? Java Basics - Anfänger-Themen 1
F String equals NULL Problem Java Basics - Anfänger-Themen 4
D Auf equals von Vaterklasse zugreifen Java Basics - Anfänger-Themen 4
S Methoden equals(object o) / toString Java Basics - Anfänger-Themen 15
E Calender - Equals Problem Java Basics - Anfänger-Themen 14
T Datentypen compareTo() u. equals() bei Strings Java Basics - Anfänger-Themen 3
Psypsy hashCode, equals und toString Java Basics - Anfänger-Themen 3
K hashCode, compareTo vs. equals Java Basics - Anfänger-Themen 3
M Vergleich zweier Array Stellen mit equals/NullpointerException Java Basics - Anfänger-Themen 9
S Unterschiede zwischen equals und contains Java Basics - Anfänger-Themen 2
F Erste Schritte Hilfe bei Übung zu String equals() und Schleifen Java Basics - Anfänger-Themen 8
A Probleme mit equals und get.Text Java Basics - Anfänger-Themen 12
S compareTo() und equals() Java Basics - Anfänger-Themen 6
R illegal start of expression - 3 Strings vergleichen mit .equals () Java Basics - Anfänger-Themen 5
K Cast bei equals Java Basics - Anfänger-Themen 2
T SQL equals Java Basics - Anfänger-Themen 4
OnDemand Methoden Equals Methde Java Basics - Anfänger-Themen 3
D if block mit equals im rumpf Java Basics - Anfänger-Themen 11
K String - Equals Java Basics - Anfänger-Themen 2
J Klassen Warum ist (a.equals(b)) gleich (a==b)? Java Basics - Anfänger-Themen 13
B Warum gibst hier Equals false zurück ? Java Basics - Anfänger-Themen 23
S Verständnissfrage equals() Java Basics - Anfänger-Themen 2
R compareTo & equals Java Basics - Anfänger-Themen 10
M Verschiedene Möglichkeiten mit 'equals' abdecken? Java Basics - Anfänger-Themen 9
M Collections Problem bei Überschreibung von hashcode() und equals() bei Hashset-Implementierung Java Basics - Anfänger-Themen 5
W Stringvergleich mit equals Java Basics - Anfänger-Themen 13
C equals() Java Basics - Anfänger-Themen 4
D Problem mit string.equals bzw string.contains Java Basics - Anfänger-Themen 4
T Problem mit der while(!string.equals("x")) Java Basics - Anfänger-Themen 2
X problem mit equals.gelöst Java Basics - Anfänger-Themen 2
M Equals überschreiben Java Basics - Anfänger-Themen 3
K equals() und hashcode() überschreiben Java Basics - Anfänger-Themen 5
K equals in Hashmap() Java Basics - Anfänger-Themen 4
B if equals(irgendeine Zahl+Buchstabe) Java Basics - Anfänger-Themen 6
T equals() und hashCode() Java Basics - Anfänger-Themen 7
D probs mit clone und equals Java Basics - Anfänger-Themen 10
3 Collections containsKey() liefert false obwohl equals() true liefert Java Basics - Anfänger-Themen 6
N Vergleich per equals Java Basics - Anfänger-Themen 5
S comparable und equals Java Basics - Anfänger-Themen 7
M Frage zu Textvergleich (equals) Java Basics - Anfänger-Themen 8
G Strings vergleichen mit equals, geht das kürzer? Java Basics - Anfänger-Themen 4
B Frage zu Funktion mit equals Java Basics - Anfänger-Themen 17
J Gibt es eine möglichkeit ähnlich wie .equals(bedingung1 ||bedingung ..n) ? Java Basics - Anfänger-Themen 5
D "2010–03–12".equals( "2010-03-12" ) Java Basics - Anfänger-Themen 6
X Frage zur Implementierung von equals() Java Basics - Anfänger-Themen 2
T Problem mit equals Java Basics - Anfänger-Themen 5
K Equals,Instanceof und "==" Java Basics - Anfänger-Themen 7
C warum liefert equals kein TRUE Java Basics - Anfänger-Themen 12
E Java hashCode equals Problem Java Basics - Anfänger-Themen 2
S equals vergleich Java Basics - Anfänger-Themen 10
H Equals hascode Java Basics - Anfänger-Themen 5
S Equals Downcast? Java Basics - Anfänger-Themen 11
D equals Vergleiche Java Basics - Anfänger-Themen 7
L String mit equals vergleichen Java Basics - Anfänger-Themen 6
neurox Tutorial equals und hashCode überschreiben Java Basics - Anfänger-Themen 33
F String equals null wird nicht angenommen. Java Basics - Anfänger-Themen 24
A Reihenfolge bei equals() Java Basics - Anfänger-Themen 2
P Toleranz bei equals Java Basics - Anfänger-Themen 4
B Frage zu equals() und hashCode() Java Basics - Anfänger-Themen 28
D String#equals + String#charAt Java Basics - Anfänger-Themen 5
S equals() - hashCode() - Contract Java Basics - Anfänger-Themen 54
G mehrere Werte für .equals ? Java Basics - Anfänger-Themen 22
T [SOLVED] Java String equals funktioniert nicht Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben