Чому GSON використовує поля, а не геттери / сетери?


79

Чому GSON використовує ТІЛЬКИ поля (приватні, загальнодоступні, захищені)? Чи є спосіб сказати GSON використовувати лише геттери та сеттери?

Відповіді:


96

Взагалі кажучи, коли ви серіалізуєте / десеріалізуєте об'єкт, ви робите це, щоб у підсумку отримати точну копію стану об'єкта; Таким чином, ви, як правило, хочете обійти інкапсуляцію, зазвичай бажану в конструкції ОО. Якщо ви не обійдете інкапсуляцію, можливо, не вдасться отримати в результаті об'єкт, який має такий самий стан після десериалізації, як і до серіалізації. Крім того, розглянемо випадок, коли ви не хочете надавати установку для певної властивості. Як повинна діяти серіалізація / десериалізація, якщо ви працюєте з геттерами та сеттерами?


28
Як щодо "обчислюваних полів", які ми хотіли б надати зовнішньому світу? Як ви думаєте, мені слід створювати поле та оновлювати це поле кожного разу, коли я оновлюю одне з полів POJO? Урх ...
Фредерік,

2
@ Frédéric - я насправді просто вказую на труднощі, які виникають при використанні методів отримання і встановлення властивостей для серіалізації; Розраховані властивості також могли б створити власні проблеми. Наприклад, якщо ви даєте комусь серіалізований об'єкт, тоді він оновлює обчислюване значення властивості та передає його вам назад, як програма повинна обробляти десеріалізацію? Робіть вигляд, що властивість не оновлено, чи виникла виняток? Крім того, якщо вони оновлюють властивості, на яких базується обчислювана властивість, стан об’єкта насправді є недійсним, і читання значення цього властивості є абсолютно неправильним.
Chris Shaffer,

1
Я згоден з @ Frédéric; є деякі випадки краю, які заслуговують на використання полів віце властивостей. Я щойно натрапив на такий, де маю байтовий масив на об’єкті, який я хотів би виключити, і замість цього повернути рядок. Тепер мені залишається адаптувати об'єкт за допомогою DTO.
Richard Clayton,

Розраховані / похідні поля повинні бути марковані, transientщоб вони не були серіалізовані, а перераховані за запитом.
BoffinBrain

14
Це чудово, якщо в якості випадку використання Java використовується серіалізація Java, але досить поширеним випадком використання є викриття об’єкта Java в результаті виклику REST api, у цьому випадку на стороні Java нам не потрібна двостороння ідеальна серіалізація, набагато частіше ми хочемо приховати поля та серіалізувати (і десериалізувати, якщо / коли це потрібно) специфічні властивості, які часто обчислюються часом.
Сімоне Джанні

26

Чи є спосіб сказати GSON використовувати лише геттери та сеттери?

Ще ні.

З дизайнерського документа :

[T] ось хороші аргументи для підтримки властивостей. Ми маємо намір вдосконалити Gson в останній версії для підтримки властивостей як альтернативного відображення для вказівки полів Json. На даний момент Gson базується на полях.


Щодо підтримки Gson для геттерів та сетерів, останнє оновлення щодо цього зі списку розсилки полягає в тому, що "[т] перспективи перетворення такої функції на Gson досить низькі ..." groups.google.com/forum/#!topic / google-gson / 4G6Lv9PghUY
Програміст Брюс

Я не думаю, що слід використовувати геттери та сетери, Кріс Шаффер пояснює це досить добре у цій відповіді.
Sentry

4
Напишіть власний серіалізатор / десериалізатор, щоб ви могли використовувати будь-який метод, який хочете, щоб записати значення назад у свій клас.
Dave Birch

2
Ця відповідь дуже стара, для таких відповідей stackoverflow потрібен якийсь "Смітник".
Азім

@jb ні. Відповідь залишається дійсним.
9ilsdx 9rvj 0lo


0

Нечіткий контур того, як це працює в нашому додатку, полягає в тому, що ми маємо багато TypeAdapterреалізацій - деякі для конкретних ціннісних об’єктів, а інші для об’єктів у стилі bean, де ми знаємо, що логіка JavaBeans буде працювати. Потім ми затискаємо все це на GsonBuilderперед тим, як створити Gsonоб’єкт.

На жаль, GSON справді безглуздо обробляти такі типи Object[]. Ми в основному бачили це, коли намагалися створити об'єкт JSON для представлення параметрів методу. Вихідним шляхом для цього було створення власних TypeAdapterпримірників, що відображають методи. (Це означає, що в кінцевому підсумку ви використовуєте по одному Gsonекземпляру для методу, який ви маєте намір викликати ...)


Як би ви розумно впоралися з десериалізацією чого-небудь для Object? Як би ви хотіли здогадатися, що це таке, щоб десериалізувати його?
9ilsdx 9rvj 0lo

Для Object, або взагалі для поліморфних речей, вони могли б мати запис атрибутів, який адаптер спочатку його серіалізував. Але з пам’яті я думаю, що навіть очевидні речі, такі як {"a", 2, "b"}, не десеріалізували Object [].
Трейказ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.