2013-09-05 20 views
43

Gson user guide besagt, dass wir Standard-No-Args-Konstruktor für jede Klasse für die ordnungsgemäße Arbeit mit Gson definieren sollten. Noch mehr, in der javadoc on Gson InstanceCreator Klasse sagte, dass eine Ausnahme ausgelöst wird, wenn wir versuchen, Instanz der Klasse fehlender Standardkonstruktor deserialize und wir solltenInstanceCreator in solchen Fällen verwenden. Ich habe jedoch versucht, Gson mit Klasse ohne Standardkonstruktor und Serialisierung und Deserialisierung ohne Probleme zu testen.Ist der Standard-Konstruktor für No-Args für Gson obligatorisch?

Hier ist der Code für Deserialisierung. Eine Klasse ohne nicht-args Konstruktor:

public class Mushroom { 
    private String name; 
    private double diameter; 

    public Mushroom(String name, double diameter) { 
     this.name = name; 
     this.diameter = diameter; 
    } 

    //equals(), hashCode(), etc. 
} 

und ein Test:

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

der gut arbeitet.

Also meine Frage ist: könnte ich tatsächlich Gson ohne Notwendigkeit, Standardkonstruktor haben oder gibt es Umstände, wenn es nicht funktioniert?

Antwort

70

Ab Gson 2.3.1.

Unabhängig davon, was die Gson Dokumentation sagt, wenn Ihre Klasse einen Konstruktor No-args nicht haben, und Sie haben keine InstanceCreater Objekte nicht registriert ist, dann wird es ein ObjectConstructor (die Konstrukte Ihr Objekt) mit einem UnsafeAllocator schaffen, die verwendet Reflection, um die allocateInstance Methode der Klasse sun.misc.Unsafe zu erhalten, um die Instanz Ihrer Klasse zu erstellen.

Diese Unsafe class geht um das Fehlen von No-Args-Konstruktor und hat many other dangerous uses. allocateInstance states

Weisen Sie eine Instanz zu, aber führen Sie keinen Konstruktor aus. Initialisiert die Klasse , falls dies noch nicht geschehen ist.

Also es braucht nicht wirklich einen Konstruktor und wird um Ihren Konstruktor mit zwei Argumenten gehen. Siehe einige Beispiele here.

Wenn Sie tun, um eine No-args Konstruktor wird Gson eine ObjectConstructor verwenden, die Constructor dass verwendet standardmäßig von

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

My 2 cents Aufruf: Folge dem, was Gson sagt und erstellen Sie Ihre Klassen mit einem nicht -arg Konstruktor oder registrieren Sie eine InstanceCreator. Sie könnten sich in einer schlechten Position mit Unsafe befinden.

+0

Was ist, wenn ich einen Standardkonstruktor habe, der mein letztes Mitglied auf null setzt, aber es gibt kein Set für dieses Mitglied? Ist das eine vernünftige Lösung? –

+1

@ thomas.mc.work Gson ist in der Lage, das Feld direkt durch Reflexion (und möglicherweise einige unsichere Arbeit) zu setzen, und Sie können es durch einen Getter (oder direkt durch das Feld abrufen. Ich empfehle dieses Design nicht. –

+0

I habe eine gute Lösung für das "final" Problem mit der hier beschriebenen Library jackson gefunden: http://stackoverflow.com/a/11838468/2854723 –