java - ejemplo - gson vs jackson
¿El constructor no-args predeterminado es obligatorio para Gson? (2)
A partir de Gson 2.3.1.
Independientemente de lo que diga la documentación de Gson, si su clase no tiene un constructor sin args y no ha registrado ningún objeto InstanceCreater
, entonces creará un ObjectConstructor
(que construye su Objeto) con un UnsafeAllocator
que usa Reflection para obtener el Método allocateInstance
de la clase sun.misc.Unsafe
para crear la instancia de su clase.
Esta clase Unsafe
va alrededor de la falta de constructor no-args y tiene muchos otros usos peligrosos . allocateInstance
estados de allocateInstance
Asigne una instancia pero no ejecute ningún constructor. Inicializa la clase si aún no ha sido.
Por lo tanto, en realidad no necesita un constructor y se utilizará en el constructor de dos argumentos. Vea algunos ejemplos here .
Si tiene un constructor sin args, Gson usará un ObjectConstructor
que usa ese Constructor
predeterminado llamando
yourClassType.getDeclaredConstructor(); // ie. empty, no-args
Mis 2 centavos: sigue lo que dice Gson y crea tus clases con un constructor sin argumentos o registra un InstanceCreator
. Puede encontrarse en una mala posición usando Unsafe
.
La guía de usuario de Gson establece que debemos definir el constructor no-args predeterminado para que cualquier clase trabaje correctamente con Gson. Aún más, en el javadoc en la clase InstanceCreator
de Gson, dijo que se lanzará una excepción si tratamos de deserializar la instancia de clase que falta el constructor predeterminado y deberíamos usar InstanceCreator
en tales casos. Sin embargo, he intentado probar el uso de Gson con la clase que carece del constructor predeterminado y tanto la serialización como la deserialización funcionan sin ningún problema.
Aquí está la pieza de código para deserializaiton. Una clase sin constructor no args:
public class Mushroom {
private String name;
private double diameter;
public Mushroom(String name, double diameter) {
this.name = name;
this.diameter = diameter;
}
//equals(), hashCode(), etc.
}
y una prueba:
@Test
public void deserializeMushroom() {
assertEquals(
new Mushroom("Fly agaric", 4.0),
new Gson().fromJson(
"{name:/"Fly agaric/", diameter:4.0}", Mushroom.class));
}
que funciona bien
Entonces mi pregunta es: ¿ podría realmente usar Gson sin necesidad de tener un constructor predeterminado o hay circunstancias en las que no funcionará?
Hay una buena solución en la biblioteca de Jackson como se describe aquí:
https://.com/a/11838468/2854723
El punto es decirle al serializador a través de la función Mix-Ins qué campos JSON usar cuando se usa el constructor con argumentos.
Si esa entidad es parte de una biblioteca externa, entonces puede "anotar a distancia" con la función Creador .