Es ist bekannt, dass die Eigenschaften, die equals () erfüllen sollte, nicht durch einfaches Implementieren der equals () -Methode einer Klasse mit einer Vererbungsbeziehung erfüllt werden können, wie unten gezeigt [(Supplement 1)](#Supplement 1). .. [* 1 Referenz](# 1) Die Problemumgehung wird auch in derselben Referenz [(Ergänzung 2)](# Ergänzung 2) beschrieben, aber die Lösung aus einem anderen Dokument [* 2 Referenz](# 2) wird beschrieben.
Erstellen Sie eine statische Methode equals () mit zwei Argumenten, wie unten gezeigt, und rufen Sie Object.equals () auf. Der wichtige Teil ist der Teil, der equals () beider Klassen aufruft. Dies kann außerhalb dieser Klassenstruktur verwendet werden. Volltext Übrigens gibt es Objects.equals (Object, Object) in der Standard-API, aber nur equals () auf der linken Seite wird aufgerufen.
ObjectUtil.java
final class ObjectUtil {
private ObjectUtil() { throw new AssertionError("Not intended to be instanciated"); }
public static boolean equals(final Object lhs, final Object rhs) {
//Gleich, wenn die Referenzziele auf der linken und rechten Seite identisch sind
if (lhs == rhs) return true;
//Gleich, wenn sowohl die linke als auch die rechte Referenz null sind
if (lhs == null && rhs == null) return true;
//Nicht dasselbe, wenn entweder das Referenzziel auf der linken Seite oder das Referenzziel auf der rechten Seite null ist
if (lhs == null || rhs == null) return false;
//Wenn die Referenzziele auf der linken und rechten Seite dieselbe Klasse sind, entspricht dies dieser Klasse()Zurückgeben
if (lhs.getClass() == rhs.getClass()) return lhs.equals(rhs);
//Wenn die Referenzen auf der linken und rechten Seite unterschiedliche Klassen sind, sind beide Klassen gleich()Und zurück
return lhs.equals(rhs) && rhs.equals(lhs);
}
}
// 1.Die Symmetrie kann nicht erfüllt werden
// ->Wenn Sie die rechte und die linke Seite tauschen, ist das Ergebnis unterschiedlich.
//Beispiel mit der oben gezeigten Klassenstruktur
Point1D p1 = new Point1D(0);
Point2D p2 = new Point2D(0, 0);
assert(p1.equals(p2) == true); //True, da nur x-Werte verglichen werden
assert(p2.equals(p1) == false); //False, um festzustellen, dass es sich um eine Point2D-Instanz handelt
// 2.Transparenz kann nicht befriedigt werden
// -> p1 == p2 && p2 ==Auch für p3, p1==Wird nicht p3
//Beispiel mit der oben gezeigten Klassenstruktur
//Annahme: Point2D.equals()Fügen Sie den Spezifikationen Folgendes hinzu
//True, auch wenn das Argument Point1D oder seine Unterklasse ist und der x-Wert gleich ist
Point2D p1 = new Point2D(0, 0);
Point1D p2 = new Point1D(0);
Point2D p3 = new Point2D(0, 1);
assert(p1.equals(p2) == true); //Richtig aufgrund neuer Spezifikationen
assert(p2.equals(p3) == true); //true, da x-Werte nicht verglichen werden
assert(p1.equals(p3) == false); // x,false, um y-Werte zu vergleichen
// 3.Das Ersatzprinzip von Riskov kann nicht erfüllt werden
// ->Ein ähnliches Verhalten wird in Unterklassen erwartet, jedoch nicht
//Beispiel mit der oben gezeigten Klassenstruktur
//Annahme 1: Point1D.equals()Ändern Sie die Spezifikationen wie folgt
//Nur wahr, wenn das Argument Point1D ist und der x-Wert gleich ist
//Annahme 2: CountingPoint1D.equals()Ändern Sie die Spezifikationen wie folgt
//Nur wahr, wenn das Argument CountingPoint1D ist und der x-Wert gleich ist
Point1D p1 = new Point(0);
CountingPoint1D cp1 = new CountingPoint(0);
CountingPoint1D cp2 = new CountingPoint(0);
List<CountingPoint1D> list = Arrays.asList(cp1);
assert(list.contains(cp2) == true); // cp1 ==wahr für cp2
assert(list.contains(p1) == false); //Falsch wegen Annahme 1
//Verwenden Sie Komposition anstelle von Vererbung
//Beispiel
class Point2D {
private final Point1D p1;
private final int y;
...
@Override
public boolean equals(Object o) {
if (!(o instanceof Point2D)) return false;
Point2D rhs = (Point2D)o;
return p1.equals(rhs.p1) && y.equals(rhs.y);
}
}
*1 Joshua Brock (2014) "Effective Java 2nd Edition" Maruzen. Punkt 8 *2 Andrey Alexandresque (2013) "Programmiersprache D" Shosuisha. 6.8.3
Recommended Posts