Java: Wenn gleich nicht gleich ist!

von Hubert Schmid vom 2012-11-18

Absurdes aus der Java-Welt: In Java gibt es für den Vergleich der Ergebnisse zweier Ausdrücke sowohl die equals-Methode als auch den Vergleichsoperator ==. Es finden sich leicht:

Doch was ist mit dem vierten Fall? Gibt es auch zwei Argumente g und h, so dass g.equals(h) falsch und g == h wahr ist?

Selbstverständlich ist das mit einer Benutzer-definierten Klasse möglich, deren equals-Methode stets false zurückgibt. Doch eine solche Implementierung würde die Spezifikation von Object.equals aufgrund der fehlenden Reflexivität verletzen. Daher akzeptiere ich diese Antwort nicht.

Die Frage lautet also konkreter: Gibt es den vierten Fall, wobei die verwendete equals-Methode die Spezifikation von Object.equals nicht verletzt?

Diese Aufgabe erscheint auf den ersten Blick unlösbar. Aber Java wäre ja nicht Java, wenn alles einfach und offensichtlich wäre. Der Schlüssel zur Lösung liegt in der Wortwahl. In der Spezifikation von Object.equals ist stets die Rede von Referenzen, die nicht null sind. Ich habe diese Formulierung bewusst vermieden.

Verwendet man als zweites Argument einen primitiven Typ, der durch das sogenannte Auto-Boxing beim equals-Aufruf in ein Object umgewandelt wird, so ist die Lösung einfach. Dazu wird noch Unboxing und Type Coercion benötigt.

public final class Test { public static void main(String... args) { Long e = new Long(42); int f = 42; System.out.println(e.equals(f)); // prints "false" System.out.println(e == f); // prints "true" } }

Fazit: Java ist immer für eine Überraschung gut.