title: Gson Type Adapter vs. Custom Deseralizer
body: <p>The example below shows a class (Club) that contains a collection of an abstract class (Member). I'm confused as to whether I need a TypeAdapter or JsonDeserializer to make the Deserialization work correctly. Serialization works just fine without any help, but Deserialization is throwing exceptions. To illustrate I've built the following "clone" test. If anyone could show a working example I would be very grateful.</p>
  
  <p>First Club Class</p>
  
  <pre><code>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&lt;Member&gt; members = new ArrayList&lt;Member&gt;();
  
      public boolean equals(Club that) {
          if (!this.title.equals(that.title)) return false;
          for (int i=0; i&lt;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); }
  }
  </code></pre>
  
  <p>Now the Abstract Base Class Member</p>
  
  <pre><code>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);}
  }
  </code></pre>
  
  <p>And two concrete sub-classes of Member (Gold and Silver)</p>
  
  <pre><code>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) &amp;&amp; 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) &amp;&amp; this.silverData.equals(that.silverData)); 
      }
  }
  </code></pre>
  
  <p>And finally the output</p>
  
  <pre><code>    {"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)
  ...
  </code></pre>