¿Por qué GSON usa campos y no getters / setters?

79

¿Por qué GSON usa SOLO campos (privados, públicos, protegidos)? ¿Hay alguna manera de decirle a GSON que use solo getters y setters?

Zemzela
fuente

Respuestas:

96

En términos generales, cuando serializa / deserializa un objeto, lo está haciendo para terminar con una copia exacta del estado del objeto; Como tal, generalmente desea eludir la encapsulación normalmente deseada en un diseño OO. Si no elude la encapsulación, es posible que no sea posible terminar con un objeto que tenga exactamente el mismo estado después de la deserialización que antes de la serialización. Además, considere el caso en el que no desea proporcionar un setter para una propiedad en particular. ¿Cómo debería actuar la serialización / deserialización si está trabajando con los captadores y definidores?

Chris Shaffer
fuente
28
¿Qué hay de los "campos calculados" que nos gustaría proporcionar al mundo exterior? En su forma de pensar, ¿debería crear un campo y actualizar este campo cada vez que actualice uno de mis campos POJO? Urgh ...
Frédéric
2
@ Frédéric - Realmente solo estoy señalando las dificultades introducidas por el uso de captadores y definidores de propiedades para la serialización; Las propiedades calculadas también introducirían sus propios problemas. Por ejemplo, si le da a alguien un objeto serializado, luego actualiza el valor de la propiedad calculada y se lo devuelve, ¿cómo debe manejar la aplicación la deserialización? ¿Fingir que la propiedad no se actualizó o lanzar una excepción? Además, si actualizan las propiedades en las que se basó la propiedad calculada, el estado del objeto en realidad no es válido y la lectura del valor de esa propiedad es completamente incorrecta.
Chris Shaffer
1
Estoy de acuerdo con @ Frédéric; Hay algunos casos extremos que merecen el uso de campos de propiedades y viceversa. Me encontré con uno en el que tengo una matriz de bytes en un objeto que me gustaría excluir y, en su lugar, devolver una Cadena. Ahora me quedo con la adaptación del objeto a través de DTO.
Richard Clayton
Los campos calculados / derivados deben etiquetarse transientpara que no se serialicen y recalcularse a pedido.
BoffinBrain
14
Esto está bien si el caso de uso es la serialización de Java a Java, pero un caso de uso bastante común es exponer un objeto Java como resultado de una llamada a la API REST, en ese caso en el lado de Java no necesitamos una serialización perfecta bidireccional, con mucha más frecuencia queremos ocultar campos y serializar (y deserializar si es necesario) propiedades específicas, a menudo calculadas en tiempo de ejecución.
Simone Gianni
26

¿Hay alguna forma de decirle a GSON que use solo getters y setters?

Aún no.

Del documento de diseño :

[E] aquí también hay buenos argumentos para respaldar las propiedades. Tenemos la intención de mejorar Gson en una última versión para admitir propiedades como un mapeo alternativo para indicar campos Json. Por ahora, Gson está basado en campos.

Programador Bruce
fuente
Con respecto al soporte de Gson para getters y setters, la última actualización de la lista de correo es que "[l] as
Programador Bruce
No creo que no deba usar getters y setters, Chris Shaffer explica esto bastante bien en esta respuesta.
Sentry
4
Escriba un serializador / deserializador personalizado, de esa manera puede usar cualquier método que desee para volver a escribir los valores en su clase.
Dave Birch
2
Esta respuesta es muy antigua, stackoverflow necesita algún "recolector de basura" para tales respuestas.
Azim
@jb nop. La respuesta sigue siendo válida.
9ilsdx 9rvj 0lo
6

Es posible parchear Gson para usar getters .

Palanqueta
fuente
1
Quiero poder designar qué variables deben usar el getter y setter
CQM
0

El esquema vago de cómo funciona esto en nuestra aplicación es que tenemos muchas TypeAdapterimplementaciones, algunas para objetos específicos de valor y otras para objetos de estilo bean, donde sabemos que la lógica de JavaBeans funcionará. Luego colocamos todos estos en un GsonBuilderantes de crear el Gsonobjeto.

Desafortunadamente, GSON es realmente una mierda para manejar tipos como Object[]. Principalmente vimos esto cuando intentábamos hacer un objeto JSON para representar parámetros de método. La solución alternativa fue crear TypeAdapterinstancias personalizadas que reflejen los métodos. (Esto significa que terminas usando una Gsoninstancia por método que pretendes llamar ...)

Trejkaz
fuente
¿Cómo manejarías con sensatez la deserialización de algo en Object? ¿Cómo le gustaría adivinar qué es eso para deserializarlo?
9ilsdx 9rvj 0lo
Para Object, o para cosas polimórficas en general, tal vez podrían tener un registro de atributo cuyo adaptador lo serializó originalmente. Pero de memoria, creo que incluso cosas obvias como {"a", 2, "b"} no se deserializaron en Object [].
Trejkaz