30

let's say i have a json array of arrays

String jsonString = [["John","25"],["Peter","37"]];

i would like to parst this into ArrayList<ArrayList<String>> objects. when i used

Gson.fromJson(jsonString,ArrayList<ArrayList<String>>.class)

it doesn't seem to work and i did a work around by using

Gson.fromJson(jsonString,String[][].class)

is there a better way to do this?

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
Thirumalai Parthasarathi
  • 4,541
  • 1
  • 25
  • 43

1 Answers1

67

Yes, use a TypeToken.

ArrayList<ArrayList<String>> list = gson.fromJson(jsonString, new TypeToken<ArrayList<ArrayList<String>>>() {}.getType());

The TypeToken allows you to specify the generic type you actually want, which helps Gson find the types to use during deserialization.

It uses this gem: Class#getGenericSuperClass(). The fact that it is an anonymous class makes it a sub class of TypeToken<...>. It's equivalent to a class like

class Anonymous extends TypeToken<...>

The specification of the method states that

If the superclass is a parameterized type, the Type object returned must accurately reflect the actual type parameters used in the source code.

If you specified

new TypeToken<String>(){}.getType();

the Type object returned would actually be a ParameterizedType on which you can retrieve the actual type arguments with ParameterizedType#getActualTypeArguments().

The type argument would be the Type object for java.lang.String in the example above. In your example, it would be a corresponding Type object for ArrayList<ArrayList<String>>. Gson would keep going down the chain until it built the full map of types it needs.

Thirumalai Parthasarathi
  • 4,541
  • 1
  • 25
  • 43
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • thanks for the quick response.. :) works like a charm.. May i know how this TypeToken gets the bounded type? i just inferred that this would be gone because of the type erasure.. – Thirumalai Parthasarathi Mar 08 '14 at 16:20
  • 2
    @BlackPanther It uses this gem: [`Class#getGenericSuperClass()`](http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getGenericSuperclass()). The fact that it is an anonymous class makes it a sub class of `TypeToken<...>`. It's equivalent to `class Anonymous extends TypeToken<...>`. The specification of the method states that `If the superclass is a parameterized type, the Type object returned must accurately reflect the actual type parameters used in the source code.` – Sotirios Delimanolis Mar 08 '14 at 16:22
  • @BlackPanther It's an old hack. [This](http://gafter.blogspot.ca/2006/12/super-type-tokens.html) should explain it further. – Sotirios Delimanolis Mar 08 '14 at 16:24
  • wow.. excellent design.. thank you so much for the info... maybe you should make it part of the answer so that others may learn the actual implementation.. – Thirumalai Parthasarathi Mar 08 '14 at 16:27
  • i understood the point you were refering... in order to call the `getGenericSuperClass` method this class has to be subclassed. god i was dumb..!! thx again...:) – Thirumalai Parthasarathi Mar 08 '14 at 16:47
  • can you take a look at [this](http://stackoverflow.com/questions/22280055/how-does-the-method-infer-the-type-of-t/22290104#22290104) question and help me..? – Thirumalai Parthasarathi Mar 10 '14 at 06:34