Il costruttore no-args predefinito è obbligatorio per Gson?

La guida utente di Gson afferma che dovremmo definire il costruttore no-args predefinito per qualsiasi class che lavori correttamente con Gson. Ancora di più, nella javadoc della class InstanceCreator di Gson abbiamo detto che verrà lanciata un’eccezione se proviamo a deserializzare l’istanza della class mancante nel costruttore predefinito e dovremmo usare InstanceCreator in questi casi. Tuttavia, ho provato a testare l’uso di Gson con una class priva del costruttore predefinito e sia la serializzazione che la deserializzazione funzionano senza problemi.

Ecco il pezzo di codice per deserializaiton. Una class senza costruttore di non-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. } 

e un test:

 @Test public void deserializeMushroom() { assertEquals( new Mushroom("Fly agaric", 4.0), new Gson().fromJson( "{name:\"Fly agaric\", diameter:4.0}", Mushroom.class)); } 

che funziona bene.

Quindi la mia domanda è: potrei effettivamente usare Gson senza bisogno di avere un costruttore di default o ci sono circostanze in cui non funzionerà?

A partire da Gson 2.3.1.

Indipendentemente da ciò che dice la documentazione di Gson, se la tua class non ha un costruttore no-args e non hai registrato alcun object InstanceCreater , allora creerà un ObjectConstructor (che costruisce il tuo Object) con un UnsafeAllocator che usa Reflection per ottenere il allocateInstance method della class sun.misc.Unsafe per creare l’istanza della class.

Questa class Unsafe gira intorno alla mancanza di costruttore no-args e ha molti altri usi pericolosi . allocateInstance stati di informazioni

Assegna un’istanza ma non esegui alcun costruttore. Inizializza la class se non è stata ancora eseguita.

Quindi non ha realmente bisogno di un costruttore e girerà attorno al tuo costruttore di due argomenti. Vedi alcuni esempi qui .

Se hai un costruttore no-args, Gson userà un ObjectConstructor che usa quel Constructor predefinito chiamando

 yourClassType.getDeclaredConstructor(); // ie. empty, no-args 

I miei 2 centesimi: segui ciò che dice Gson e crea le tue classi con un costruttore no-arg o registra un InstanceCreator . Potresti trovarti in una brutta posizione usando Unsafe .

C’è una buona soluzione nella libreria di Jackson come descritto qui:

https://stackoverflow.com/a/11838468/2854723

Il punto è di dire al serializzatore tramite la funzione Mix-In quali campi JSON usare quando si usa il costruttore con argomenti.

Se quell’ quadro fa parte di una libreria esterna, allora puoi “annotare a distanza” con la funzione Creatore .