有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么我不能按我需要的方式使用TypeToken?

我试图解决反序列化HashMap<Integer, MyParcelablePojo>时遇到的一个问题。为了找到答案,我发现了以下问题:

如果我尝试:

HashMap<Integer, MyParcelablePojo> mHashMap = new Gson().fromJson(the_json_string, HashMap.class);

。。。结果HashMap包含LinkedTreeMap个对象,而不是MyParcelablePojo个对象

因此,我尝试以与上面链接的第二个问题类似的方式使用TypeToken,但它不允许我指定HashMap的参数。如果我尝试:

// XXX I am not sure if this "Type" is the correct one
//     there were several "Type" classes to choose from
import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

Type collection_type = new TypeToken<HashMap<Integer, MyParcelablePojo>>();

。。。Android Studio向我显示了以下错误:

'TypeToken()' has protected access in 'com.google.gson.reflect.TypeToken'

。。。只是为了坚持我看到的例子,我试着用new TypeToken<HashMap<T>>看看错误是否消失了(只是出于好奇,我根本不想用泛型T来解决这个问题),然后它说“无法解决T”,这太奇怪了。。。但这与我的问题无关,我只是为了完整性添加了它

回到点,所以TypeToken的构造函数受到保护,对吗?所以,扩展类可能会有所帮助,对吗?但是如果我看到构造器,我就很难理解它。参数化类型以这种方式使用非常奇怪(至少就我目前对它们的理解而言)。部分<? super T>有点令人困惑(看起来它调用的是T的父类型,但我不完全理解)。但是,对我来说更奇怪的是$Gson$Types.getRawType(type)。。。我想知道那些$是用来做什么的:

protected TypeToken() {
    this.type = getSuperclassTypeParameter(getClass());
    this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
    this.hashCode = type.hashCode();
}

直截了当

我只是想避免Gson.fromJson方法将LinkedTreeMap作为值返回,而不是MyParcelablePojo。相关问题中提供的答案对我来说太笼统了,所以我不知道如何将它们应用到我的案例中(请注意,我现在对泛型不感兴趣)。我甚至怀疑它们是否适用于我的情况

我使用HashMap的主要动机是因为我想自己定义索引,使用ID基础。我应该怎么做才能正确地解决从JSON字符串反序列化的问题


共 (3) 个答案

  1. # 1 楼答案

    如果您正在使用kotlin,请不要忘记使用对象:

    val type: Type = object : TypeToken<ArrayList<YourArrayType>>() {}.type
    
  2. # 2 楼答案

    我认为你没有正确使用TypeToken,我一直在做

    HashMap<Integer, GenericObject> mHashMap = new Gson().fromJson(json, new TypeToken<HashMap<Integer, GenericObject>>(){}.getType());
    

    传递类型,而不是实际的令牌

  3. # 3 楼答案

    通过创建一个子类来实例化TypeToken,该子类通常是匿名的:

    Type collection_type = new TypeToken<HashMap<Integer, MyParcelablePojo>>(){}.getType();
    

    注意我答案中的{}。原因在JavaDoc中有解释:

    /**
     * Represents a generic type {@code T}. Java doesn't yet provide a way to
     * represent generic types, so this class does. Forces clients to create a
     * subclass of this class which enables retrieval the type information even at
     * runtime.
     *
     * <p>For example, to create a type literal for {@code List<String>}, you can
     * create an empty anonymous inner class:
     *
     * <p>
     * {@code TypeToken<List<String>> list = new TypeToken<List<String>>() {};}
     *
     * <p>This syntax cannot be used to create type literals that have wildcard
     * parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}.
     *
     * @author Bob Lee
     * @author Sven Mawson
     * @author Jesse Wilson
     */