Search code examples
androidserializationdeserializationjson-deserializationgson

Deserializing ArrayList<Interface> using GSON


I have a class Shop

public class Shop {

  private String name;
  private ArrayList<Fruitable> fruits;


  public String toJson() {
     Gson gson = new Gson();
     return gson.toJson(this, Shop.class) 
  }   

}

Apple and Orange are the two classes that implements Fruitable interface.

Fruitable:

public interface Fruitable {
   String getColor();
}

Apple:

public class Apple implements Fruitable {

 private int Id;     

 @Override
 public String getColor() {
    return "red";
  }

 }

Orange:

 public class Orange implements Fruitable {

 private int Id;

 @Override
 public String getColor() {
    return "orange";
  }

 }

I can serialize Shop using GSON, however, I cannot deserialize it properly.

When I deserialize, the ArrayList<Fruitable> has objects, but the objects are null.

This is because GSON requires a concrete instance to deserialze into.

I know I can implement JsonDeserializer in Shop.

However, can I implement some deserializing mechanism, inside Apple and Orange so they will deserialize themselves?

If that is not possible, and I have to write a deserializer in Shop, can I write code just to deserialize the fruits property and not the other properties,i.e. GSON will deserialize the remaining properties assuming they are concrete instances?


Solution

  • Ok so you should use GSON annotations they will make your life a whole lot easier. An example:

    public class Deal{
    
       @SerializedName("name")
       String name;
    
       @SerializedName("times")
       List<DealTime> times;
    
    }
    

    The json coming back will roughly look this:

    {
       name:dave,
       times[
         {
          end:400,
          start:200
         },
         {
          end:30,
          start:500
         }
       ]
    }
    

    Then your DealTime class will have the following:

       public class DealTime{
    
           @SerializedName("end")
           int end;
    
           @SerializedName("start")
           int start;
    
        }
    

    All you have to do is cast the json coming back with GSON using the Deal object. Hope this helps.