Warum verwendet GSON Felder und keine Getter / Setter?

79

Warum verwendet GSON NUR Felder (privat, öffentlich, geschützt)? Gibt es eine Möglichkeit, GSON anzuweisen, nur Getter und Setter zu verwenden?

Zemzela
quelle

Antworten:

96

Wenn Sie ein Objekt serialisieren / deserialisieren, erhalten Sie im Allgemeinen eine exakte Kopie des Objektstatus. Daher möchten Sie im Allgemeinen die Kapselung umgehen, die normalerweise in einem OO-Design gewünscht wird. Wenn Sie die Kapselung nicht umgehen, ist es möglicherweise nicht möglich, ein Objekt zu erhalten, das nach der Deserialisierung genau den gleichen Status aufweist wie vor der Serialisierung. Betrachten Sie außerdem den Fall, in dem Sie keinen Setter für eine bestimmte Eigenschaft bereitstellen möchten. Wie sollte Serialisierung / Deserialisierung funktionieren, wenn Sie die Getter und Setter durcharbeiten?

Chris Shaffer
quelle
28
Wie wäre es mit "berechneten Feldern", die wir der Außenwelt zur Verfügung stellen möchten? Nach Ihrer Auffassung sollte ich jedes Mal, wenn ich eines meiner POJO-Felder aktualisiere, ein Feld erstellen und dieses Feld aktualisieren. Urgh ...
Frédéric
2
@ Frédéric - Ich möchte wirklich nur auf Schwierigkeiten hinweisen, die durch die Verwendung von Property Getter und Setter für die Serialisierung entstehen. Berechnete Eigenschaften würden auch ihre eigenen Probleme mit sich bringen. Wenn Sie beispielsweise jemandem ein serialisiertes Objekt geben, aktualisiert dieser den Wert der berechneten Eigenschaft und gibt ihn an Sie zurück. Wie sollte die Anwendung mit der Deserialisierung umgehen? Stellen Sie sich vor, die Eigenschaft wurde nicht aktualisiert oder lösen Sie eine Ausnahme aus? Wenn sie die Eigenschaften aktualisieren, auf denen die berechnete Eigenschaft basiert, ist der Objektstatus tatsächlich ungültig, und das Lesen des Werts dieser Eigenschaft ist völlig falsch.
Chris Shaffer
1
Ich stimme @ Frédéric zu; Es gibt einige Randfälle, die die Verwendung von Vice-Feldern für Eigenschaften verdienen. Ich bin gerade auf eines gestoßen, bei dem ich ein Byte-Array für ein Objekt habe, das ich ausschließen und stattdessen einen String zurückgeben möchte. Jetzt muss ich das Objekt über DTO anpassen.
Richard Clayton
Berechnete / abgeleitete Felder sollten gekennzeichnet werden, transientdamit sie nicht serialisiert und auf Anfrage neu berechnet werden.
BoffinBrain
14
Dies ist in Ordnung, wenn es sich bei dem Anwendungsfall um eine Java-zu-Java-Serialisierung handelt. Ein recht häufiger Anwendungsfall besteht jedoch darin, ein Java-Objekt als Ergebnis eines REST-API-Aufrufs verfügbar zu machen. In diesem Fall benötigen wir auf der Java-Seite keine perfekte Zwei-Wege-Serialisierung. Viel häufiger möchten wir Felder ausblenden und bestimmte, häufig zur Laufzeit berechnete Eigenschaften serialisieren (und bei Bedarf deserialisieren).
Simone Gianni
26

Gibt es eine Möglichkeit, GSON anzuweisen, nur Getter und Setter zu verwenden?

Noch nicht.

Aus dem Designdokument :

[T] hier sind gute Argumente, um auch Eigenschaften zu unterstützen. Wir beabsichtigen, Gson in einer späteren Version zu verbessern, um Eigenschaften als alternative Zuordnung zum Anzeigen von Json-Feldern zu unterstützen. Derzeit ist Gson feldbasiert.

Programmierer Bruce
quelle
In Bezug auf die Gson-Unterstützung für Getter und Setter ist das neueste Update aus der Mailingliste, dass "die Aussichten für eine solche Funktion in Gson ziemlich gering sind ..." groups.google.com/forum/#!topic / google-gson / 4G6Lv9PghUY
Programmierer Bruce
Ich denke nicht, dass man Getter und Setter verwenden sollte, Chris Shaffer erklärt dies in dieser Antwort ziemlich gut.
Wachposten
4
Schreiben Sie einen benutzerdefinierten Serializer / Deserializer. Auf diese Weise können Sie jede Methode verwenden, mit der Sie die Werte zurück in Ihre Klasse schreiben möchten.
Dave Birch
2
Diese Antwort ist sehr alt, Stackoverflow benötigt für solche Antworten einen "Garbage Collector".
Azim
@jb nein. Die Antwort ist noch gültig.
9ilsdx 9rvj 0lo
6

Es ist möglich, Gson zu patchen, um Getter zu verwenden .

Jimmy
quelle
1
Ich möchte in der Lage sein zu
bestimmen,
0

Der vage Umriss, wie dies in unserer App funktioniert, ist, dass wir viele TypeAdapterImplementierungen haben - einige für bestimmte wertähnliche Objekte und einige für Objekte im Bean-Stil, bei denen wir wissen, dass die JavaBeans-Logik funktioniert. Wir jammen dann alle diese auf ein, GsonBuilderbevor wir das GsonObjekt erstellen .

Leider ist GSON wirklich beschissen im Umgang mit Typen wie Object[]. Wir haben dies meistens gesehen, als wir versucht haben, ein JSON-Objekt zur Darstellung von Methodenparametern zu erstellen. Die Problemumgehung bestand darin, benutzerdefinierte TypeAdapterInstanzen zu erstellen, die die Methoden widerspiegeln. (Dies bedeutet, dass Sie am Ende eine GsonInstanz pro Methode verwenden, die Sie aufrufen möchten ...)

Trejkaz
quelle
Wie würden Sie vernünftig damit umgehen, etwas an Object zu deserialisieren? Wie möchten Sie erraten, was das ist, um es zu deserialisieren?
9ilsdx 9rvj 0lo
Für Object oder für polymorphes Material im Allgemeinen könnten sie möglicherweise einen Attributdatensatz haben, der vom Adapter ursprünglich serialisiert wurde. Aber aus dem Gedächtnis denke ich, dass selbst offensichtliche Dinge wie {"a", 2, "b"} nicht zu Object [] deserialisiert wurden.
Trejkaz