Gson TypeToken with dynamic ArrayList item type

前端 未结 9 1986
情深已故
情深已故 2020-11-22 08:55

I have this code:

Type typeOfObjectsList = new TypeToken>() {}.getType();
List objectsList = new Gson().fromJso         


        
相关标签:
9条回答
  • 2020-11-22 09:18

    The syntax you are proposing is invalid. The following

    new TypeToken<ArrayList<Class.forName(MyClass)>>
    

    is invalid because you're trying to pass a method invocation where a type name is expected.

    The following

    new TypeToken<ArrayList<T>>() 
    

    is not possible because of how generics (type erasure) and reflection works. The whole TypeToken hack works because Class#getGenericSuperclass() does the following

    Returns the Type representing the direct superclass of the entity (class, interface, primitive type or void) represented by this Class.

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

    In other words, if it sees ArrayList<T>, that's the ParameterizedType it will return and you won't be able to extract the compile time value that the type variable T would have had.

    Type and ParameterizedType are both interfaces. You can provide an instance of your own implementation.

    0 讨论(0)
  • 2020-11-22 09:19

    You can do this with Guava's more powerful TypeToken:

    private static <T> Type setModelAndGetCorrespondingList2(Class<T> type) {
        return new TypeToken<ArrayList<T>>() {}
                .where(new TypeParameter<T>() {}, type)
                .getType();
    }
    
    0 讨论(0)
  • 2020-11-22 09:24

    sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl workes. No need for custom implementation

    Type type = ParameterizedTypeImpl.make(List.class, new Type[]{childrenClazz}, null);
    List list = gson.fromJson(json, type);
    

    Can be used with maps and any other collection:

    ParameterizedTypeImpl.make(Map.class, new Type[]{String.class, childrenClazz}, null);
    

    Here is nice demo how you can use it in custom deserializer: Deserializing ImmutableList using Gson

    0 讨论(0)
提交回复
热议问题