2

I use Gson for serialize and deserialize json.

pojo class :

class myData{
    public String id;
    public String name;
 }

and with this code i get that json to pojo class.

public static Object getData(Class clazz)  {
    String json = "{'name':'john','id':'123'}";
        Gson gson = new Gson();
        return gson.fromJson(json , clazz);
}



//usage:
myData mdata= (myData) getData(myData.class);

every thing goes fine, in read array from json i have this method:

ArrayList<myData> getDatas() {
        ArrayList<myData> mdatas = new ArrayList<>();
        String json ="[{'name':'john','code':'123'},{'name':'nick','code':'456'}]";
        Type listType = new TypeToken<ArrayList<myData>>() {
        }.getType();
        if (new Gson().fromJson(json, listType) != null) {
            return new Gson().fromJson(json, listType);
        } else {
            return mdatas;
        }
}

that code was fine. but i want to pass any class in getDatas and find that class in json then return list of that class in result.

something like this:

 ArrayList<?> getDatas(Class clazz) {
    ArrayList<clazz> mdatas = new ArrayList<>();  //this line is the problem
    String json = "[{'name':'john','code':'123'},{'name':'nick','code':'456'}]";
    //and this line
    Type listType = new TypeToken<ArrayList<clazz>>() {
    }.getType();
    if (new Gson().fromJson(json, listType) != null) {
        return new Gson().fromJson(json, listType);
    } else {
        return mdatas;
    }
}

problem is cant use anonymous class in arraylist.

 ArrayList<clazz> mdatas = new ArrayList<>(); 
 Type listType = new TypeToken<ArrayList<clazz>>() {

is any way to use arraylist with anonymous class?

javadroid
  • 1,421
  • 2
  • 19
  • 43
  • When you try your code then what you faced issue? – Farmer May 13 '17 at 05:32
  • yes their is way to get it done check this: http://stackoverflow.com/questions/18421674/using-gson-to-parse-a-json-array, just pass your responseString & your class name, it will return you List of you class type. – vivek mahajan May 13 '17 at 05:37
  • @vivekmahajan goal is create method with pass a class as parameter and find pojo class of that in json. – javadroid May 13 '17 at 06:02
  • Possible duplicate of [Java Type Generic as Argument for GSON](http://stackoverflow.com/questions/14139437/java-type-generic-as-argument-for-gson) – tima May 14 '17 at 13:45

2 Answers2

1

Your problem is that an instance of type "Class" is not the same as a generic type.

Consider the following:

<T> ArrayList<T> getDatas(Class<T> clazz) {
    ArrayList<T> mdatas = new ArrayList<>();  //this line is the problem
    String json = "[{'name':'john','code':'123'},{'name':'nick','code':'456'}]";
    //and this line
    Type listType = new TypeToken<ArrayList<T>>() {
    }.getType();
    if (new Gson().fromJson(json, listType) != null) {
        return new Gson().fromJson(json, listType);
    } else {
        return mdatas;
    }
}

This will give the type in as generic type bound to the function and it can be used at the places where you used the clazz parameter in this case, making it unnecessary to pass it in.

Wietlol
  • 1,001
  • 1
  • 10
  • 25
1

It's easy if you pass either type tokens (for compile-time type safety) or any Type instances.

Using type tokens

The source below can be any of String, Reader and JsonReader (see the fromJson overloads).

static <E> List<E> getList(final ... source, final TypeToken<? extends List<E>> listTypeToken) {
    return gson.fromJson(source, listTypeToken.getType());
}

Example of use:

final List<MyData> list = getList(jsonReader, new TypeToken<List<MyData>>() {
});

By the way, TypeToken and Gson instances are thread-safe and can be cached to static final fields.

Using any types without type tokens

static <E> List<E> getList(final ... source, final Type type) {
    return gson.fromJson(source, getParameterized(List.class, type).getType());
}

This case creates ParameterizedType instance using the newer Gson version. Note that you can create a type dynamically (not to be confused with creating a class): you specify both parameterized type List and parameterize it with the given type.

Example of use:

final List<MyData> list = getList(jsonReader, MyData.class);

If you cannot use the newest Gson versions, you have to create a ParameterizedType instance yourself like this (the anonymous class interface is easy to understand):

static <E> List<E> getListForOlderGson(final ... source, final Type type) {
    return gson.fromJson(source, new ParameterizedType() {
        @Override
        public Type getRawType() {
            return List.class;
        }

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

        @Override
        public Type getOwnerType() {
            return null;
        }
    });
}
Lyubomyr Shaydariv
  • 20,327
  • 12
  • 64
  • 105