Gson Type Adapter vs. Custom Deseralizer

Das folgende Beispiel zeigt eine Klasse (Club), die eine Sammlung einer abstrakten Klasse (Member) enthält. Ich bin verwirrt, ob ich einen TypeAdapter oder JsonDeserializer benötige, damit die Deserialisierung korrekt funktioniert. Die Serialisierung funktioniert einwandfrei, aber bei der Deserialisierung treten Ausnahmen auf. Um das zu veranschaulichen, habe ich den folgenden "Klontest" erstellt. Wenn jemand ein funktionierendes Beispiel zeigen könnte, wäre ich sehr dankbar.

First Club Class

package gson.test;
import java.util.ArrayList;

import com.google.gson.Gson;

public class Club {
    public static void main(String[] args) {
        // Setup a Club with 2 members
        Club myClub = new Club();
        myClub.addMember(new Silver());
        myClub.addMember(new Gold());

        // Serialize to JSON
        Gson gson = new Gson();
        String myJsonClub = gson.toJson(myClub); 
        System.out.println(myJsonClub);

        // De-Serialize to Club
        Club myNewClub = gson.fromJson(myJsonClub, Club.class);
        System.out.println(myClub.equals(myNewClub) ? "Cloned!" : "Failed");
    }

    private String title = "MyClub";
    private ArrayList<Member> members = new ArrayList<Member>();

    public boolean equals(Club that) {
        if (!this.title.equals(that.title)) return false;
        for (int i=0; i<this.members.size(); i++) {
            if (! this.getMember(i).equals(that.getMember(i))) return false;
        }
        return true;
    }
    public void addMember(Member newMember) { members.add(newMember); }
    public Member getMember(int i) { return members.get(i); }
}

Nun das abstrakte Basisklassenmitglied

package gson.test;
public abstract class Member {
    private int type;
    private String name = "";

    public int getType() { return type; }
    public void setType(int type) { this.type = type; }
    public boolean equals(Member that) {return this.name.equals(that.name);}
}

Und zwei konkrete Unterklassen von Mitgliedern (Gold und Silber)

package gson.test;
public class Gold extends Member {
    private String goldData = "SomeGoldData";
    public Gold() {
        super();
        this.setType(2);
    }
    public boolean equals(Gold that) {
        return (super.equals(that) && this.goldData.equals(that.goldData)); 
    }
}

package gson.test;
public class Silver extends Member {
    private String silverData = "SomeSilverData";
    public Silver() {
        super();
        this.setType(1);
    }
    public boolean equals(Silver that) { 
        return (super.equals(that) && this.silverData.equals(that.silverData)); 
    }
}

Und schließlich die Ausgabe

    {"title":"MyClub","members":[{"silverData":"SomeSilverData","type":1,"name":""},{"goldData":"SomeGoldData","type":2,"name":""}]}
    Exception in thread "main" java.lang.RuntimeException: Failed to invoke public gson.test.Member() with no args
        at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:107)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:186)
...

Antworten auf die Frage(6)

Ihre Antwort auf die Frage