Почему GSON использует поля, а не геттеры / сеттеры?

Почему GSON использует ТОЛЬКО поля (частные, общедоступные, защищенные)? Есть ли способ указать GSON использовать только геттеры и сеттеры?


person Zemzela    schedule 01.06.2011    source источник


Ответы (4)


Вообще говоря, когда вы сериализуете / десериализуете объект, вы делаете это для получения точной копии состояния объекта; Таким образом, вы обычно хотите обойти инкапсуляцию, обычно желаемую в объектно-ориентированном дизайне. Если вы не обойдете инкапсуляцию, возможно, не удастся получить объект, который после десериализации будет иметь такое же состояние, как и до сериализации. Кроме того, рассмотрите случай, когда вы не хотите предоставлять сеттер для определенного свойства. Как должна действовать сериализация / десериализация, если вы работаете через геттеры и сеттеры?

person Chris Shaffer    schedule 01.06.2011
comment
А как насчет вычисляемых полей, которые мы хотели бы предоставить внешнему миру? Как вы думаете, я должен создавать поле и обновлять это поле каждый раз, когда я обновляю одно из своих полей POJO? Ух ... - person Frédéric Camblor; 16.10.2012
comment
@ Frédéric - Я просто указываю на трудности, возникающие при использовании методов получения и установки свойств для сериализации; Вычисляемые свойства также вызовут свои собственные проблемы. Например, если вы дадите кому-то сериализованный объект, а затем они обновят значение вычисленного свойства и вернут его вам, как приложение должно обрабатывать десериализацию? Притворяться, что свойство не обновлялось, или генерировать исключение? Кроме того, если они обновляют свойства, на которых было основано вычисленное свойство, состояние объекта фактически недействительно, а чтение значения этого свойства однозначно неверно. - person Chris Shaffer; 16.10.2012
comment
Я согласен с @ Frédéric; есть некоторые крайние случаи, которые заслуживают использования полей свойств. Я только что столкнулся с одним, где у меня есть массив байтов для объекта, который я хотел бы исключить и вместо этого вернуть String. Теперь мне осталось адаптировать объект через DTO. - person Richard Clayton; 24.10.2012
comment
Вычисляемые / производные поля должны быть помечены transient, чтобы они не сериализовались и не пересчитывались по запросу. - person BoffinBrain; 06.02.2013
comment
Обычно, когда я сериализую объект в JSON, я делаю это, чтобы сообщить что-то другой стороне. Обычно, когда я десериализую объект из JSON, я делаю это потому, что кто-то отправил его мне в JSON. Все классы моделей в нашей системе написаны только как интерфейс и затем используют прокси-серверы отражения для реализации. Пытаться сериализовать поля в этой ситуации просто глупо - сериализация свойств сделала бы такой прокси-сервер отражения неотличимым от bean-компонента, закодированного вручную (что хорошо). - person Trejkaz; 05.04.2013
comment
Это нормально, если вариантом использования является сериализация Java в Java, но довольно распространенный вариант использования - предоставить объект Java в результате вызова API REST, в этом случае на стороне Java нам не нужна двухсторонняя идеальная сериализация, гораздо чаще мы хотим скрыть поля и сериализовать (и десериализовать, если / когда необходимо) определенные, часто вычисляемые во время выполнения, свойства. - person Simone Gianni; 28.10.2013
comment
Наличие возможности указать сериализатору использовать геттеры и сеттеры для данного класса позволит выполнить проверку Hibernate для параметра установщика. - person Stephane; 20.11.2015
comment
@ Frédéric, мне сегодня пришлось иметь дело с временным вычисляемым полем. Я просто вычислил это в геттере, если null. - person BlueWizard; 11.12.2016
comment
Если вы так сильно хотите использовать свой Getter / Setter, вы можете просто предоставить собственный сериализатор. Я делаю это постоянно, и это очень просто и понятно (Tutorial sites.google.com/site/gson/). Часто у меня есть метод fromJson внутри самого объекта - person BlueWizard; 11.12.2016

Есть ли способ указать GSON использовать только геттеры и сеттеры?

Еще нет.

Из проектной документации:

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

person Programmer Bruce    schedule 01.06.2011
comment
Что касается поддержки Gson для геттеров и сеттеров, последнее обновление этого списка рассылки состоит в том, что перспективы внедрения такой функции в Gson довольно низки ... groups.google.com/forum / #! topic / google-gson / 4G6Lv9PghUY - person Programmer Bruce; 02.07.2011
comment
Я не думаю, что не следует использовать геттеры и сеттеры, Крис Шаффер довольно хорошо объясняет это в этом ответе. - person Sentry; 09.10.2012
comment
Напишите собственный сериализатор / десериализатор, чтобы вы могли использовать любой метод, которым хотите записать значения обратно в свой класс. - person Dave Birch; 15.12.2014
comment
Этот ответ очень старый, stackoverflow действительно нуждается в сборщике мусора для таких ответов. - person Azim; 10.08.2016
comment
@jb нет. Ответ все еще в силе. - person 9ilsdx 9rvj 0lo; 10.04.2017
comment
Я думаю, можно с уверенностью предположить, что они не добавят эту функцию на данном этапе. - person JaviCasa; 08.06.2017

Можно исправить Gson для использования геттеров.

person Jimmy    schedule 18.06.2011
comment
Я хочу иметь возможность указывать, какие переменные должны использовать геттер и сеттер - person CQM; 15.05.2014

Расплывчатый план того, как это работает в нашем приложении, заключается в том, что у нас есть много TypeAdapter реализаций - некоторые для конкретных объектов, подобных значению, а некоторые для объектов в стиле bean, где мы знаем, что логика JavaBeans будет работать. Затем мы вставляем все это в GsonBuilder перед созданием объекта Gson.

К сожалению, GSON действительно плохо справляется с такими типами, как Object[]. В основном мы видели это, когда пытались создать объект JSON для представления параметров метода. Чтобы решить эту проблему, нужно создать собственные TypeAdapter экземпляры, отражающие методы. (Это означает, что вы в конечном итоге используете один Gson экземпляр для каждого метода, который собираетесь вызвать ...)

person Trejkaz    schedule 05.04.2013
comment
Как бы вы разумно справились с десериализацией чего-либо в Object? Как бы вы хотели угадать, что это такое, чтобы десериализовать его? - person 9ilsdx 9rvj 0lo; 10.04.2017
comment
Для Object или для полиморфного материала в целом они, возможно, могут иметь запись атрибута, адаптер которой изначально сериализовал ее. Но по памяти, я думаю, что даже такие очевидные вещи, как {a, 2, b}, не десериализовались в Object []. - person Trejkaz; 12.04.2017