简体   繁体   中英

Java: Dynamic List Type to cast Json array

Well, I have this: A number of webservices, each webservice returns an array of one entity. Good!

In my Android app, I call the webservices and get the Json String with the array of elements.

To make it some dynamically I made an array with the cast classes names, example:

<item>com.company.package.Person</item>
<item>com.company.package.Animal</item>
<item>com.company.package.Thing</item>
// etc

The idea was:

  1. Load the array with the name of the class to cast the JSON

     String[] entities = getResources().getStringArray(R.array.classNames); 
  2. Get a Class type with Class.forName(...)

     Class<?> object = Class.forName(entities[y]); 
  3. Always the webservices returns an array, then I want to convert the Json to Java List like this

     //see the **object**, this was my idea but doesn't work Type type = new TypeToken<List<**object**>() {}.getType(); List<**object**> array = gson.fromJson(jsonArrayString, type); 

Any way to do this?

This works

I found a way to do it

Write my own ParameterizedType list (@ andersschuller answer) and with this

Class<?> clazz = Class.forName(entities[y]);
Type type = new ParameterizedTypeList(clazz.newInstance().getClass());
List<? extends Object> array = SystemUtils.factoryGson().fromJson(datos.get(y).toString(), type);

Solved my problem with 3 lines (maybe less than this)

Hope help anyone!

I believe there is no way to do what you are trying to do with the TypeToken . However, GSON can in fact handle any ParameterizedType being passed into the gson.fromJson method, and it is relatively straightforward to implement this interface.

In your specific case, we want to build a type whose raw type is List , and whose type argument is either Person , Animal or Thing . The following class allows us to build such types:

public static class ListType implements ParameterizedType {
    private final Class<?> elementClass;

    public ListType(Class<?> elementClass) {
        this.elementClass = elementClass;
    }

    @Override
    public Type[] getActualTypeArguments() {
        return new Type[]{elementClass};
    }

    @Override
    public Type getRawType() {
        return List.class;
    }

    @Override
    public Type getOwnerType() {
        return null;
    }
}

Assuming we then have some JSON like

String json = "[{\"name\": \"Charlie\"}]";

and Person and Animal classes that have a "name" property, we can then deserialize this JSON into lists by using an appropriate ListType instance:

List<Person> people = gson.fromJson(json, new ListType(Person.class));
System.out.println(people.get(0).getClass().getSimpleName());            // prints Person
System.out.println(people.get(0).name);                                  // prints Charlie

List<Animal> animals = gson.fromJson(json, new ListType(Animal.class));
System.out.println(animals.get(0).getClass().getSimpleName());           // prints Animal
System.out.println(animals.get(0).name);                                 // prints Charlie

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM