Es ist ein entscheidender Punkt, aber meiner Meinung nach ist es wert, verstanden zu werden.
Alle OO-Sprachen machen immer Kopien von Referenzen und kopieren niemals ein Objekt 'unsichtbar'. Es wäre viel schwieriger, Programme zu schreiben, wenn die OO-Sprachen anders funktionieren würden. Beispielsweise könnten Funktionen und Methoden ein Objekt niemals aktualisieren. Java und die meisten OO-Sprachen wären ohne zusätzliche Komplexität kaum zu verwenden.
Ein Objekt in einem Programm soll eine Bedeutung haben. Zum Beispiel repräsentiert es etwas Bestimmtes in der realen physischen Welt. In der Regel ist es sinnvoll, viele Verweise auf dasselbe zu haben. Beispielsweise kann meine Privatadresse vielen Personen und Organisationen zugewiesen werden, und diese Adresse bezieht sich immer auf denselben physischen Standort. Der erste Punkt ist also, dass Objekte oft etwas Spezifisches, Reales oder Konkretes darstellen. und so ist es äußerst nützlich, in der Lage zu sein, viele Verweise auf dasselbe zu haben. Sonst wäre es schwieriger, Programme zu schreiben.
Jedes Mal, wenn Sie a
als Argument / Parameter an eine andere Funktion übergeben, z. B.
foo(Dog aDoggy);
eine Methode aufrufen oder anwenden a
, erstellt der zugrunde liegende Programmcode eine Kopie der Referenz, um eine zweite Referenz auf dasselbe Objekt zu erstellen.
Wenn sich der Code mit einer kopierten Referenz in einem anderen Thread befindet, können beide gleichzeitig verwendet werden, um auf dasselbe Objekt zuzugreifen.
In den meisten nützlichen Programmen wird es also mehrere Verweise auf dasselbe Objekt geben, da dies die Semantik der meisten OO-Programmiersprachen ist.
Nun, wenn wir darüber nachdenken, da die Referenzübergabe der einzige Mechanismus ist, der in vielen OO-Sprachen verfügbar ist (C ++ unterstützt beide), können wir davon ausgehen, dass dies das 'richtige' Standardverhalten ist .
IMHO ist die Verwendung von Referenzen aus mehreren Gründen die richtige Standardeinstellung :
- Es garantiert, dass der Wert eines Objekts, das an zwei verschiedenen Orten verwendet wird, derselbe ist. Stellen Sie sich vor, Sie platzieren ein Objekt in zwei verschiedene Datenstrukturen (Arrays, Listen usw.) und führen einige Operationen an einem Objekt durch, das es ändert. Das könnte ein Albtraum sein, um zu debuggen. Noch wichtiger ist, dass es sich in beiden Datenstrukturen um dasselbe Objekt handelt oder dass das Programm einen Fehler aufweist.
- Sie können Code problemlos in mehrere Funktionen umgestalten oder den Code aus mehreren Funktionen in einer Funktion zusammenführen, ohne dass sich die Semantik ändert. Wenn die Sprache keine Referenzsemantik bereitstellen würde, wäre das Ändern von Code noch komplexer.
Es gibt auch ein Effizienzargument; Das Kopieren ganzer Objekte ist weniger effizient als das Kopieren einer Referenz. Ich denke jedoch, dass das den Punkt verfehlt. Mehrfachverweise auf dasselbe Objekt sind sinnvoller und einfacher zu verwenden, da sie der Semantik der realen physischen Welt entsprechen.
Also, meiner Meinung nach, ist es normalerweise sinnvoll, mehrere Verweise auf dasselbe Objekt zu haben. In den ungewöhnlichen Fällen, in denen dies im Kontext eines Algorithmus keinen Sinn ergibt, bieten die meisten Sprachen die Möglichkeit, einen "Klon" oder eine tiefe Kopie zu erstellen. Dies ist jedoch nicht die Standardeinstellung.
Ich denke, Leute, die argumentieren, dass dies nicht der Standard sein sollte, verwenden eine Sprache, die keine automatische Speicherbereinigung bietet. Zum Beispiel altmodisches C ++. Das Problem dabei ist, dass sie einen Weg finden müssen, um "tote" Objekte zu sammeln und keine Objekte zurückzugewinnen, die möglicherweise noch benötigt werden. Mehrere Verweise auf dasselbe Objekt machen dies schwierig.
Ich denke, wenn C ++ eine ausreichend kostengünstige Garbage Collection hätte, so dass alle referenzierten Objekte Garbage Collected sind, dann verschwindet ein Großteil der Einwände. Es wird immer noch Fälle geben, in denen die Referenzsemantik nicht erforderlich ist. Nach meiner Erfahrung sind die Personen, die diese Situationen identifizieren können, jedoch in der Regel auch in der Lage, die entsprechende Semantik zu wählen.
Ich glaube, es gibt Hinweise darauf, dass ein großer Teil des Codes in einem C ++ - Programm dazu dient, die Garbage Collection zu handhaben oder zu mildern. Das Schreiben und Verwalten dieser Art von "Infrastruktur" -Code verursacht jedoch zusätzliche Kosten. Es ist dazu da, die Sprache benutzerfreundlicher oder robuster zu machen. So wurde beispielsweise die Sprache Go mit dem Schwerpunkt entwickelt, einige der Schwächen von C ++ zu beheben, und es bleibt keine andere Wahl als die Garbage Collection.
Dies ist im Kontext von Java natürlich irrelevant. Es wurde ebenfalls so konzipiert, dass es einfach zu bedienen ist, ebenso wie die Garbage Collection. Daher ist das Vorhandensein mehrerer Referenzen die Standard-Semantik und in dem Sinne relativ sicher, dass Objekte nicht zurückgefordert werden, solange eine Referenz auf sie vorhanden ist. Natürlich könnten sie von einer Datenstruktur festgehalten werden, da das Programm nicht richtig aufräumt, wenn es wirklich mit einem Objekt fertig ist.
Wenn Sie sich also (mit ein wenig Verallgemeinerung) wieder Ihrer Frage widmen, wann möchten Sie mehr als einen Verweis auf dasselbe Objekt? So ziemlich in jeder Situation, die mir einfällt. Sie sind die Standardsemantik der meisten Übergabemechanismen für Sprachparameter. Ich schlage vor, das liegt daran, dass die Standardsemantik für den Umgang mit Objekten, die in der realen Welt vorhanden sind, so gut wie per Referenz festgelegt werden muss (weil die tatsächlichen Objekte da draußen sind).
Jede andere Semantik wäre schwieriger zu handhaben.
Dog a = new Dog("rover"); // initialise with name
DogList dl = new DogList()
dl.add(a)
...
a.setOwner("Mr Been")
Ich schlage vor, dass der "Rover" dl
derjenige sein sollte, der von setOwner
Programmen ausgeführt wird oder der schwer zu schreiben, zu verstehen, zu debuggen oder zu modifizieren ist. Ich denke, die meisten Programmierer wären sonst verwirrt oder bestürzt.
später wird der Hund verkauft:
soldDog = dl.lookupOwner("rover", "Mr Been")
soldDog.setOwner("Mr Mcgoo")
Diese Art der Verarbeitung ist üblich und normal. Daher ist die Referenzsemantik die Standardeinstellung, da sie normalerweise am sinnvollsten ist.
Zusammenfassung: Es ist immer sinnvoll, mehrere Referenzen auf dasselbe Objekt zu haben.