我有这段代码:
public abstract class Repository<Entity extends BaseObject> {
...
public void readFromJson(){
String content = "JSON content here";
Gson gson = new Gson();
Type entityType = new TypeToken<JSONObject<Entity>>(){}.getType();
jsonObject = gson.fromJson(content, entityType);
for (Entity ent : jsonObject.getEntities()) ;
}
}
当我尝试执行foreach时,我的实体对象不再是Entity类型而是LinkedHashMap,我得到以下异常:java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为com.tranca.bookstore.domain。 shared.BaseObject
这是JSONObject类(由我创建)
public class JSONObject<Entity> {
private List<Entity> entities = new ArrayList<Entity>();
private long lastId = -1;
public List<Entity> getEntities() {
return entities;
}
public void setEntities(List<Entity> entities) {
this.entities = entities;
}
public long getLastId() {
return lastId;
}
public void setLastId(long lastId) {
this.lastId = lastId;
}
public void incrementLastId() {
this.lastId++;
}
}
也许基础对象是相关的,所以我将把代码放在这里:
public abstract class BaseObject implements Serializable {
protected long id = (long) -1;
protected int version = 0;
protected BaseObject(){}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
答案 0 :(得分:3)
我有同样/类似的问题。在稍微不同的背景下给出更明确的答案:
我有以下方法产生错误&#34; com.google.gson.internal.LinkedTreeMap无法转换为MyType&#34;:
/**
* Reads a LinkedHashMap from the specified parcel.
*
* @param <TKey>
* The type of the key.
* @param <TValue>
* The type of the value.
* @param in
* The in parcel.
* @return Returns an instance of linked hash map or null.
*/
public static <TKey, TValue> LinkedHashMap<TKey, TValue> readLinkedHashMap(Parcel in) {
Gson gson = JsonHelper.getGsonInstance();
String content = in.readString();
LinkedHashMap<TKey, TValue> result = gson.fromJson(content, new TypeToken<LinkedHashMap<TKey, TValue>>(){}.getType());
return result;
}
我想要一种简单的通用方法来读/写链接的hashmap。上面的解决方案不起作用,因为据我所知,编译后,带有TKey和TValue的TypeToken的类型信息将会丢失。这就是问题所在。如果您将代码更改为以下示例,那么它可以正常工作,因为现在我们明确定义了类型标记。我不太了解java,我理解为什么在这种情况下可以在运行时读取类型信息。
/**
* Reads a LinkedHashMap from the specified parcel.
*
* @param <TKey>
* The type of the key.
* @param <TValue>
* The type of the value.
* @param in
* The in parcel.
* @return Returns an instance of linked hash map or null.
*/
public static <TKey, TValue> LinkedHashMap<TKey, TValue> readLinkedHashMap(Parcel in, TypeToken<LinkedHashMap<TKey, TValue>> typeToken) {
Gson gson = JsonHelper.getGsonInstance();
Type type = typeToken.getType();
String content = in.readString();
LinkedHashMap<TKey, TValue> result = gson.fromJson(content, type);
return result;
}
现在你可以调用上面的函数:
readLinkedHashMap(in, new TypeToken<LinkedHashMap<UUID, MyObject>>(){});
旁注1:在写入链接的哈希映射时,您根本不需要指定任何类型的令牌。 toJson(地图)就足够了。
旁注2(对于我遇到的问题):默认情况下,gson使用toString()来序列化密钥。如果为密钥类型注册类型适配器(可能是更复杂的类型),则在序列化时,但在反序列化时不应用此类型适配器。这导致不一致且因此失败的过程。以下选项会激活complex map key serialization。
gsonBuilder.enableComplexMapKeySerialization()
答案 1 :(得分:2)
终于搞定了!
问题在于:
new TypeToken&lt;的JSONObject&LT;实体GT;&GT;(){}的getType();
返回JSONObject的类型&lt; T&GT;而不是扩展Repository的子类的特定实体(例如,UserRepository扩展了Repository&lt; User&gt;)。
诀窍是创建一个抽象方法来强制子类设置反序列化的类型。
总之,如果你得到这个错误,请确保你有正确的类类型(如果你使用子类,请确保它返回你的子类的类型而不是超类)。