Ich habe diese Klasse:
%Vor%Das ist offensichtlich ein schlechter Stil, weil ich einen gemeinsamen veränderbaren Zustand einführe. Was ist der bevorzugte Weg, um damit umzugehen?
BEARBEITEN: Um zu verdeutlichen, warum das schlecht ist, stell dir folgendes vor:
%Vor% Wenn Sie nur die Referenz speichern, können Sie Daten in das private Feld myObject.data
injizieren, obwohl es vollständig privat sein sollte.
Abhängig von der Art von MyClass
könnte dies schwerwiegende Auswirkungen haben.
Der beste Weg ist, den Parameter tief zu klonen. Aus Leistungsgründen ist dies in der Regel nicht möglich. Darüber hinaus können nicht alle Objekte geklont werden, so dass tiefes Kopieren Ausnahmen auslösen kann und alle Arten von Kopfschmerzen verursachen kann.
Der nächstbeste Weg wäre ein "Copy-on-Write" -Klon. In der Java-Laufzeitumgebung wird dies nicht unterstützt.
Wenn Sie glauben, dass jemand die Sammlung mutieren kann, führen Sie eine flache Kopie mit dem Kopierkonstruktor aus:
%Vor%Dies wird Ihr Problem lösen (da String unveränderlich ist), aber es wird fehlschlagen, wenn der Typ in der Menge veränderbar ist.
Eine andere Lösung besteht darin, die Sets immer unveränderlich zu machen, sobald Sie sie irgendwo speichern:
%Vor%Die Idee ist, Sammlungen so schnell wie möglich in "Wertobjekte" umzuwandeln. Jeder, der die Sammlung ändern möchte, muss sie kopieren, ändern und dann speichern.
Innerhalb einer Klasse können Sie das Set veränderbar halten und es in den Getter einbinden (was Sie ohnehin tun sollten).
Probleme mit diesem Ansatz: Leistung (aber es ist wahrscheinlich nicht so schlimm, wie Sie erwarten würden) und Disziplin (bricht, wenn Sie es irgendwo vergessen).
Hängt stark von Ihren Anforderungen ab.
Bearbeitet: Ignorieren sollte keine Option sein. Silent Fail ist, naja ... ein Albtraum für das Debugging.
Entschuldigen Sie, dass ich Ihre Bedenken nicht direkt angesprochen habe, aber ich würde niemals eine Sammlung direkt an eine setXxx () - Bean-Setter-Methode übergeben. Stattdessen würde ich tun:
%Vor%Ich würde mich für defensives Kopieren / Deep Cloning nur dann entscheiden, wenn ich sicher bin, dass es keine Nebenwirkungen bei der Verwendung geben würde, und was die Geschwindigkeit angeht, würde ich mich nicht damit beschäftigen, da die Zuverlässigkeit von Business-Anwendungen 10 Mal beträgt mehr Priorität als Geschwindigkeit. ; -)
Eine Idee wird sein, die Daten als String-Array zu übergeben und das Set in MyClass zu erstellen. Natürlich sollte MyClass testen, dass die Eingabedaten gültig sind. Ich glaube, dass dies ohnehin eine gute Praxis ist.
Wenn sowohl der Aufrufer von MyClass als auch MyClass selbst mit einem Set<String>
arbeiten, könnten Sie das Klonen der Sammlung in Betracht ziehen. Das Set muss jedoch irgendwie konstruiert werden. Ich würde es vorziehen, diese Verantwortung auf MyClass zu verschieben.
Tags und Links java