Die meisten OO-Sprachen folgen der Semantik 'Variablen enthalten Referenzen auf Objekte'. Der Zuweisungsoperator = und der Vergleichsoperator == beziehen sich dann immer auf Referenzen, nicht auf den Wert (Inhalt) der Objekte.

int x; Point pa = new Point(2,5); // Erzeuge Objekt von Typ Point, pa enthält Referenz darauf Point pb = pa; // pb enthält jetzt gleiche Referenz wie pa x = pa.getX(); // liefert x = 2 pb.move(1,1); // pb bewegen auf (3,6) // Überraschung! x = pa.getX(); // liefert x = 3, weil pa und pb dasselbe Objekt referenzieren
Eine auf pb angewandte Mutator-Methode ändert den Wert des referenzierten Objekts. Damit verändert sich auch der über pa abgefragte X-Wert. Wenn zwei Variablen nach einer Zuweisung ein jeweils eigenes Objekt referenzieren sollen, muss daher eine echte Kopie des Objekts erzeugt werden. Dieser Vorgang wird als copy by value oder cloning bezeichnet. Er besteht prinzipiell aus drei Stufen:

Beim Vergleichen von zwei Variablen muss ebenfalls darauf geachtet werden, was wirklich verglichen wird: Referenzen oder Werte. Im folgenden Code
String name = new String ("Hallo");
if (name == "Hallo") // true oder false ?
...
wird eine String-Variable name mit einem String-Literal "Hallo" verglichen.

Das String-Literal entspricht einem temporären lokalen Objekt. Erfolgt der Vergleich per Referenz, wird false geliefert, denn es handelt sich um zwei distinkte Objekte. (In der Praxis ist die Sache sogar noch komplizierter: Der Compiler könnte die beiden "Hallo" Literale auf das gleiche Objekt legen, um Platz zu sparen - dann liefert der Vergleich true, aber das Ergebnis ist dann compilerabhängig und das ist das Letzte, was Programmierer wollen.)

Um sicherzugehen, dass nicht Referenzen sondern die tatsächlichen Werte der Objekte verglichen werden, muss der Vergleichsoperator == überladen werden (C++) oder eine besondere Methode equals definiert werden (Java). Wie beim Kopieren ist auch beim Vergleichen das gewünschte Verhalten für die spezifische Klasse zu klären.

Ein Vorteil einer Methode wie equals ist, dass sie für die Klasse angepasst werden kann. So kann bei einer Klasse Name folgender Vergleich wahr sein:
Name n = new Name("Müller");
Name m = new Name("Mueller");
// Methode equals implementiert Vergleich von deutschen Wörten
if (n.equals(m)) // Vergleich liefert true
....