Funktionen, die "exklusives Eigentum" an neu erstellten veränderlichen Objekten zurückgeben, sollten häufig der spezifischste praktische Typ sein. Diejenigen, die unveränderliche Objekte zurückgeben, insbesondere wenn sie gemeinsam genutzt werden, sollten häufig weniger spezifische Typen zurückgeben.
Der Grund für die Unterscheidung ist, dass im ersteren Fall ein Objekt immer in der Lage sein wird, ein neues Objekt des angegebenen Typs zu erzeugen, und da der Empfänger das Objekt besitzt und nicht bekannt ist, welche Aktionen der Empfänger dort ausführen möchte Im Allgemeinen kann der Code, der das Objekt zurückgibt, nicht wissen, ob alternative Schnittstellenimplementierungen die Anforderungen des Empfängers erfüllen können.
Im letzteren Fall bedeutet die Tatsache, dass das Objekt unveränderlich ist, dass die Funktion möglicherweise einen alternativen Typ identifizieren kann, der alles kann, was ein komplizierterer Typ aufgrund seines genauen Inhalts tun könnte . Beispielsweise kann eine Immutable2dMatrix
Schnittstelle von einer ImmutableArrayBacked2dMatrix
Klasse und einer ImmutableDiagonal2dMatrix
Klasse implementiert werden . Eine Funktion, die ein Quadrat Immutable2dMatrix
zurückgeben soll, könnte entscheiden, eine ImmutableDiagonalMatrix
Instanz zurückzugeben, wenn alle Elemente außerhalb der Hauptdiagonale Null sind, oder ImmutableArrayBackedMatrix
wenn nicht. Der erstere Typ würde viel weniger Speicherplatz beanspruchen, aber der Empfänger sollte sich nicht um den Unterschied zwischen ihnen kümmern.
Durch die Rückgabe Immutable2dMatrix
anstelle eines konkreten ImmutableArrayBackedMatrix
Codes kann der Code den Rückgabetyp basierend auf dem Inhalt des Arrays auswählen. Dies bedeutet auch, dass, wenn der Code, der das Array zurückgeben soll, eine geeignete Implementierung enthält Immutable2dMatrix
, dies einfach zurückgegeben werden kann, anstatt eine neue Instanz erstellen zu müssen . Diese beiden Faktoren können bei der Arbeit mit unveränderlichen Objekten zu großen "Gewinnen" führen.
Bei der Arbeit mit veränderlichen Objekten kommt jedoch keiner der beiden Faktoren ins Spiel. Die Tatsache, dass ein veränderliches Array beim Generieren möglicherweise keine Elemente außerhalb der Hauptdiagonale enthält, bedeutet nicht, dass es niemals solche Elemente enthält. Während a ImmutableDiagonalMatrix
effektiv ein Subtyp von Immutable2dMatrix
a MutableDiagonalMatrix
ist , ist a folglich kein Subtyp von a Mutable2dMatrix
, da das letztere Speicher außerhalb der Hauptdiagonale akzeptieren könnte, während das erstere dies nicht kann. Während unveränderliche Objekte häufig gemeinsam genutzt werden können und sollten, können veränderbare Objekte dies im Allgemeinen nicht. Eine Funktion, die nach einer neuen veränderlichen Sammlung gefragt wird, die mit bestimmten Inhalten initialisiert wurde, muss eine neue Sammlung erstellen, unabhängig davon, ob ihr Sicherungsspeicher dem angeforderten Typ entspricht oder nicht.
ArrayList
ist unbekannt, und wir können diese Frage unmöglich beantworten, selbst wenn wir uns den Quellcode von ansehenCollections
.