OOP Objekte als Return-Werte: Einen Klon zurückgeben oder Instanz auf das Feld?

Skrodde

Aktives Mitglied
Hallo zusammen,
ich habe in meinem Projekt mehrere Klassen, welche als Felder weitere Objekte gespeichert haben, z.B.
Java:
public class LinearFunction implements Function{	
	private List<OptTerm> terms;
	private Number constantTerm;

	public void setTerms(List<OptTerm> terms) {
	}

	public List<OptTerm> getTerms() {
	}
}
Nun meine Fragen:
  • Sollte man direkt die Referenz auf das Objekt (hier die Liste) zurückgeben und darauf vertrauen, dass der Anwender nicht in der Liste schreibt, wenn man nicht möchte, oder sollte man die Liste duplizieren?
  • Im letzteren Fall: Ich habe gelesen, dass .clone() nur eine Kopie, aber keine Deep-Kopie erzeugt. Gibt es eine bessere Möglichkeit, als alle Klassen, die ich habe mit einer eigenen Clone() Methode auszustatten, welche dann eine Deep-Copy erzeugt?
Vielen Dank und Gruß, Martin
 
Hallo,
vielen Dank für die Antworten soweit. Der Typ mit der Collections-Methode ist ja schon mal super. Damit habe ich wohl die Hälfte des Aufwands erschlagen. Für den Rest werde ich wohl die verlinkte Klasse nutzen, dann bin ich bei allem auf der sicheren Seite.
Allerdings habe ich jetzt die Klassen-Methode
Code:
public static Object clone(Object copyObject)
ausprobiert und bekomme eine
Code:
java.io.NotSerializableException
Komme ich nun nicht vom Regen in die Traufe? Ich muss zwar
Code:
clone()
nicht mehr bei jedem Objekt implementieren, dafür aber jedes Objekt serialisierbar machen , oder? 🙁
 
nur fuers clonen sollte man kein Serializable brauchen, serialisierst du deine Objekte auch ?
 
Zuletzt bearbeitet von einem Moderator:
nur fuers clonen sollte man kein Serializable brauchen, serialisierst du deine Objekte auch ?
Mit der oben genannten Klasse können wohl nur serialisierbare Objekte geklont werden.
Nach dem Kommentar von Maki mache ich mir lieber selbst noch Gedanken, ob ich nicht irgendwie verhindern kann, dass ich Klonen oder Ähnliches überhaupt brauche. Das alles scheint doch komplizierter zu sein, als ich dachte. :autsch:
 
Sollte man direkt die Referenz auf das Objekt (hier die Liste) zurückgeben und darauf vertrauen, dass der Anwender nicht in der Liste schreibt, wenn man nicht möchte, oder sollte man die Liste duplizieren?

Das "Sollte man" solltest du entscheiden. Der "Anwender" ist ja in der Regel ein Entwickler. Prinzipiell spricht erst mal nichts dagegen, dass er deine Klasse nutzt und auch die Daten manipuliert, soweit es ihm möglich ist. Hat die Manipulation Auswirkungen auf andere Klassen, könnte man schon drüber nachdenken.
Aber ich persönlich kenne fast gar keine Fälle, wo jemand mal eine Deep Copy gebraucht habe, weil er Angst haben musste, dass jemand etwas verändert und es Auswirkungen haben könnte. Soll nicht heißen, dass man es nie braucht, nur dass es einfach auf dein Anwendungfall drauf ankommt. Und wie gesagt, es ist ja kein "Anwender" im eigentlichen Sinne ... es ist immer noch ein Entwickler, der deine Klasse nutzt und auch wissen sollte, was passiert, wenn er was ändert (sofern du es ihm dokumentierst 😀).
 
Das mit der Rückgabe ist über Collections#unmodifiableList ja weitgehend geklärt. Die Frage nach der "Tiefe" stellt sich noch
linearFunction.getTerms().get(0).modifyThisInSomeWay(); // Erlaubt?

Aber zum Setter wurde noch nichts gesagt. Was würdest du da reinschreiben? Ein einfaches
Java:
public void setTerms(List<OptTerm> terms) 
{
    this.terms = terms;
}
würde die Collections#unmodifiableList nämlich ggf. ad absurdum führen. Man sollte auch in Betracht ziehen, gar keinen setter für die Liste anzubieten, sondern nur add/remove, womit man die (im Konstruktor erstellte, finale, private) Liste füllen kann.
 

Zurück
Oben