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 Immutable2dMatrixSchnittstelle von einer ImmutableArrayBacked2dMatrixKlasse und einer ImmutableDiagonal2dMatrixKlasse implementiert werden . Eine Funktion, die ein Quadrat Immutable2dMatrixzurückgeben soll, könnte entscheiden, eine ImmutableDiagonalMatrixInstanz zurückzugeben, wenn alle Elemente außerhalb der Hauptdiagonale Null sind, oder ImmutableArrayBackedMatrixwenn 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 Immutable2dMatrixanstelle eines konkreten ImmutableArrayBackedMatrixCodes 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 ImmutableDiagonalMatrixeffektiv ein Subtyp von Immutable2dMatrixa MutableDiagonalMatrixist , 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.
ArrayListist unbekannt, und wir können diese Frage unmöglich beantworten, selbst wenn wir uns den Quellcode von ansehenCollections.