Hallo zusammen,
Mich interessiert momentan ein Problem, das wir kürzlich hatten / haben. Es existiere folgendes FunctionalInterface:
Ich habe hier der Übersicht halber mal auf die JavaDoc verzichtet. Was die jeweilige Implementierung tun soll, dürfte aber klar sein.
Ich weiß, dass es ähnliche Konstrukte auch z.B. in JavaFx gibt (dort der klassische ChangeListener, welcher letztlich das Observable, den oldValue und den newValue annimmt).
Meine Frage hierzu ist nun, ob es eine Möglichkeit gibt, sicher mit mutable Objects umzugehen und dabei zu vermeiden, dass beim Aufruf des Listeners gilt oldValue == newValue.
Wir hatten hier einige Möglichkeiten diskutiert. Eine war, die ChangeListener bereits über Änderungen zu informieren, bevor die eigentliche Operation ausgeführt worden ist. Also quasi (wieder vereinfacht dargestellt):
Das hätte allerdings den Nachteil, dass die Listener bereits über eine Änderung informiert worden sind, die noch gar nicht stattgefunden hat und die im schlimmsten Falle ggf. gar nicht stattfindet, da z.B. ein Fehler fliegt. Tauschen wir in der oben genannten Methode die Zeilen schlicht aus und speichern uns den aktuellen Wert für einen Moment zwischen, dann funktioniert das natürlich tadellos für alle None mutable objects. Für die übrigen wäre die Implementierung reichlich sinnfrei, da der alte und der neue Wert nun natürlich gleich sind. Die Referenz wurde ja ersetzt.
Gibt es eine Methode, wie man dieses Problem sauber umgehen kann, wenn man das Object nicht kennt? Im oben genannten Beispiel ist es dem Listener erstmal vollkommen egal, was T denn überhaupt ist. Ich kann also nicht sicherstellen, dass das Objekt tatsächlich nicht mutable ist oder mir eine Möglichkeit bietet, eine echte Kopie zu erzeugen. Schließlich weiß ich hierbei nicht, ob ein Clonable-Interface (sauber) implementiert ist, ob das Objekt
Serializable implementiert oder mir den DefaultKonstruktor (für newInstance() und den Zusammebau via Reflection z.B.) zur Verfügung stellt o.Ä.. Das wäre zumindest die mir bekannten Methoden, mit BoardMitteln eine echte Kopie erzeugen zu können.
Gibt es hier eine Möglichkeit? Haben wir in unserer Diskussion vielleicht auch etwas gänzlich naheliegendes schlicht übersehen?
Natürlich könnte man hier einen anderen parametrisierten Typen erzwingen, der z.B. eine Kopierbarkeit oder Ähnliches sicherstellt - aber das ist hier tatsächlich gar nicht Sinn und Zweck der Frage.
Im Team haben wir uns mittlerweile gegen diesen ChangeListener entschieden und etwas anderes angestrebt. Mich beschäftigt diese Frage allerdings immer noch aus privater Neugierde.
Mich interessiert momentan ein Problem, das wir kürzlich hatten / haben. Es existiere folgendes FunctionalInterface:
Java:
@FunctionalInterface
public interface ChangeListener<T> {
void changed(T oldValue, T newValue);
}
Ich habe hier der Übersicht halber mal auf die JavaDoc verzichtet. Was die jeweilige Implementierung tun soll, dürfte aber klar sein.
Ich weiß, dass es ähnliche Konstrukte auch z.B. in JavaFx gibt (dort der klassische ChangeListener, welcher letztlich das Observable, den oldValue und den newValue annimmt).
Meine Frage hierzu ist nun, ob es eine Möglichkeit gibt, sicher mit mutable Objects umzugehen und dabei zu vermeiden, dass beim Aufruf des Listeners gilt oldValue == newValue.
Wir hatten hier einige Möglichkeiten diskutiert. Eine war, die ChangeListener bereits über Änderungen zu informieren, bevor die eigentliche Operation ausgeführt worden ist. Also quasi (wieder vereinfacht dargestellt):
Java:
void set(Foo newValue) {
notifyListener(this.value, newValue);
this.value = newValue;
}
Das hätte allerdings den Nachteil, dass die Listener bereits über eine Änderung informiert worden sind, die noch gar nicht stattgefunden hat und die im schlimmsten Falle ggf. gar nicht stattfindet, da z.B. ein Fehler fliegt. Tauschen wir in der oben genannten Methode die Zeilen schlicht aus und speichern uns den aktuellen Wert für einen Moment zwischen, dann funktioniert das natürlich tadellos für alle None mutable objects. Für die übrigen wäre die Implementierung reichlich sinnfrei, da der alte und der neue Wert nun natürlich gleich sind. Die Referenz wurde ja ersetzt.
Gibt es eine Methode, wie man dieses Problem sauber umgehen kann, wenn man das Object nicht kennt? Im oben genannten Beispiel ist es dem Listener erstmal vollkommen egal, was T denn überhaupt ist. Ich kann also nicht sicherstellen, dass das Objekt tatsächlich nicht mutable ist oder mir eine Möglichkeit bietet, eine echte Kopie zu erzeugen. Schließlich weiß ich hierbei nicht, ob ein Clonable-Interface (sauber) implementiert ist, ob das Objekt
Serializable implementiert oder mir den DefaultKonstruktor (für newInstance() und den Zusammebau via Reflection z.B.) zur Verfügung stellt o.Ä.. Das wäre zumindest die mir bekannten Methoden, mit BoardMitteln eine echte Kopie erzeugen zu können.
Gibt es hier eine Möglichkeit? Haben wir in unserer Diskussion vielleicht auch etwas gänzlich naheliegendes schlicht übersehen?
Natürlich könnte man hier einen anderen parametrisierten Typen erzwingen, der z.B. eine Kopierbarkeit oder Ähnliches sicherstellt - aber das ist hier tatsächlich gar nicht Sinn und Zweck der Frage.
Im Team haben wir uns mittlerweile gegen diesen ChangeListener entschieden und etwas anderes angestrebt. Mich beschäftigt diese Frage allerdings immer noch aus privater Neugierde.