google/gson

Gson deserialize Object array problem

Closed this issue · 2 comments

When deserialize with type of object[], gson cannot get the right type.
Code like :

@Test
 public void testGsonObjectArray() throws Exception{
   Gson gson = new Gson();
   Object[] objects = new Object[2];
   objects[0] = 100;
   objects[1] = new Inner(1);
   Outer outer = new Outer(1, "outer-instance1", objects);
   String jsonString = gson.toJson(outer);
   System.out.println("Gson#toJson result :" + jsonString);
   Outer outerDeser = gson.fromJson(jsonString, Outer.class);
   System.out.println("Gson#fromJson result : " + outerDeser);

   System.out.println(outerDeser.objects[0].getClass());
   System.out.println(outerDeser.objects[1].getClass());
 }
 class Outer{
   private int id;
   private String name;
   private Object [] objects;

   public Outer(int id, String name, Object[] objects) {
     this.id = id;
     this.name = name;
     this.objects = objects;
   }
   @Override
   public String toString() {
     return "Outer{" +
             "id=" + id +
             ", name='" + name + '\'' +
             ", objects=" + Arrays.toString(objects) +
             '}';
   }
 }

 class Inner{
   private int id;

   public Inner(int id) {
     this.id = id;
   }
 }

The test result is :
Gson#toJson result :{"id":1,"name":"outer-instance1","objects":[100,{"id":1}]}
Gson#fromJson result : Outer{id=1, name='outer-instance1', objects=[100.0, {id=1.0}]}
class java.lang.Double
class com.google.gson.internal.LinkedTreeMap

Is there any way to handle this?

There is no other way of doing this unless you specify concrete types in your mappings (no Object[] at all, but Integer and Inner fields directly), or you implement your custom deserializer trying to "guess" how to deserialize such an object (using a sort of duck typing mechanics) probably supplying some type information right into JSON documents.

@lyubomyr-shaydariv Thanks for your reply.
I was looking for some feature like SerializerFeature.WriteClassName in fastjson, which makes the deserialize quit easy and concise.
Actually, the object[] represents the parameters for a method which invoked by reflect , so I don't know the concrete type before the they are passed to the method.
One way I came up with is I should add one field for type information against the object[] , like :

class Outer{
   private int id;
   private String name;
   private Object [] objects;
   private Class[] clzs;
 }

By this, I can get the type when deserialize .