Dlaczego GSON używa pól, a nie getters / setters?

79

Dlaczego GSON używa TYLKO pól (prywatnych, publicznych, chronionych)? Czy istnieje sposób, aby powiedzieć GSON, aby używał tylko metod pobierających i ustawiających?

Zemzela
źródło

Odpowiedzi:

96

Ogólnie mówiąc, gdy serializujesz / deserializujesz obiekt, robisz to, aby otrzymać dokładną kopię stanu obiektu; W związku z tym na ogół chcesz obejść hermetyzację normalnie pożądaną w projekcie OO. Jeśli nie ominiesz hermetyzacji, może nie być możliwe uzyskanie obiektu, który ma dokładnie taki sam stan po deserializacji, jak przed serializacją. Dodatkowo weź pod uwagę przypadek, w którym nie chcesz podawać metody ustawiającej dla określonej właściwości. Jak powinna działać serializacja / deserializacja, jeśli pracujesz przez metody pobierające i ustawiające?

Chris Shaffer
źródło
28
A co z „polami obliczeniowymi”, które chcielibyśmy udostępnić światu zewnętrznemu? W twoim sposobie myślenia powinienem utworzyć pole i aktualizować to pole za każdym razem, gdy aktualizuję jedno z moich pól POJO? Urgh ...
Frédéric
2
@ Frédéric - Tak naprawdę tylko wskazuję na trudności, które pojawiają się przy używaniu metod pobierających i ustawiających właściwości do serializacji; Obliczone właściwości wprowadziłyby również własne problemy. Na przykład, jeśli dasz komuś zserializowany obiekt, a następnie zaktualizuje on obliczoną wartość właściwości i przekaże Ci ją z powrotem, w jaki sposób aplikacja powinna obsługiwać deserializację? Udawać, że właściwość nie została zaktualizowana lub zgłosić wyjątek? Ponadto, jeśli zaktualizują właściwości, na których została oparta obliczona właściwość, stan obiektu jest w rzeczywistości nieprawidłowy, a odczyt wartości tej właściwości jest błędny.
Chris Shaffer,
1
Zgadzam się z @ Frédéric; jest kilka skrajnych przypadków, w których warto używać pól właściwości imadła. Właśnie natknąłem się na taki, w którym mam tablicę bajtów na obiekcie, który chciałbym wykluczyć i zamiast tego zwrócić String. Teraz pozostaje mi zaadaptowanie obiektu przez DTO.
Richard Clayton,
Pola obliczeniowe / wyprowadzone powinny być oznaczone etykietami, transientaby nie były serializowane i przeliczane na żądanie.
BoffinBrain
14
Jest to w porządku, jeśli przypadkiem użycia jest serializacja Java do Java, ale dość powszechnym przypadkiem użycia jest ujawnienie obiektu Java w wyniku wywołania REST api, w takim przypadku po stronie Java nie potrzebujemy dwukierunkowej doskonałej serializacji, znacznie częściej chcemy ukrywać pola i serializować (i deserializować w razie potrzeby) specyficzne, często obliczane w czasie wykonywania, właściwości.
Simone Gianni,
26

Czy istnieje sposób, aby powiedzieć GSON, aby używał tylko metod pobierających i ustawiających?

Jeszcze nie.

Z dokumentu projektowego :

[T] tutaj są również dobre argumenty przemawiające za właściwościami. Zamierzamy ulepszyć Gson w ostatniej wersji, aby obsługiwać właściwości jako alternatywne mapowanie do wskazywania pól Json. Na razie Gson jest oparty na polach.

Programista Bruce
źródło
Jeśli chodzi o obsługę Gson dla metod pobierających i ustawiających, najnowszą aktualizacją na liście mailingowej jest to, że „perspektywy wprowadzenia takiej funkcji do Gson są dość niskie ...” groups.google.com/forum/#!topic / google-gson / 4G6Lv9PghUY
Programmer Bruce
Myślę, że nie powinienem używać getterów i seterów, Chris Shaffer wyjaśnia to całkiem dobrze w tej odpowiedzi.
Sentry
4
Napisz niestandardowy serializator / deserializator, w ten sposób możesz użyć dowolnej metody, którą chcesz zapisać z powrotem do swojej klasy.
Dave Birch,
2
Ta odpowiedź jest bardzo stara, przepełnienie stosu potrzebuje do tego „Garbage Collectora”.
Azim
@jb nope. Odpowiedź jest nadal aktualna.
9ilsdx 9rvj 0lo
6

Możliwe jest zaktualizowanie Gson, aby używał getterów .

Jimmy
źródło
1
Chcę móc wyznaczyć, które zmienne powinny używać metody pobierającej i ustawiającej
CQM
0

Ogólny zarys tego, jak to działa w naszej aplikacji, jest taki, że mamy wiele TypeAdapterimplementacji - niektóre dla określonych obiektów typu wartości, a niektóre dla obiektów w stylu fasoli, w przypadku których wiemy, że logika JavaBeans będzie działać. Następnie jamujemy je wszystkie na a GsonBuilderprzed utworzeniem Gsonobiektu.

Niestety, GSON jest naprawdę kiepski w obsłudze typów takich jak Object[]. Widzieliśmy to głównie podczas próby utworzenia obiektu JSON do reprezentowania parametrów metody. Rozwiązaniem było utworzenie niestandardowych TypeAdapterinstancji, które odzwierciedlają metody. (Oznacza to, że w końcu używasz jednej Gsoninstancji na metodę, którą zamierzasz wywołać ...)

Trejkaz
źródło
Jak rozsądnie poradzisz sobie z deserializacją czegokolwiek do Object? Jak chciałbyś zgadnąć, co to jest, aby go deserializować?
9ilsdx 9rvj 0lo
W przypadku obiektu lub w ogóle polimorficznych rzeczy mogliby mieć rekord atrybutu, który adapter pierwotnie go serializował. Ale z pamięci, myślę, że nawet oczywiste rzeczy, takie jak {"a", 2, "b"} nie zdeserializowały się do Object [].
Trejkaz