GSON转换为LinkedHashMap而不是我的对象

我有这段代码:

public abstract class Repository { ... public void readFromJson(){ String content = "JSON content here"; Gson gson = new Gson(); Type entityType = new TypeToken<JSONObject>(){}.getType(); jsonObject = gson.fromJson(content, entityType); for (Entity ent : jsonObject.getEntities()) ; } } 

当我尝试执行foreach时,我的实体对象不再是Entity类型而是LinkedHashMap,我得到以下exception:java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为com.tranca.bookstore.domain.shared.BaseObject

这是JSONObject类(由我创建)

 public class JSONObject { private List entities = new ArrayList(); private long lastId = -1; public List getEntities() { return entities; } public void setEntities(List 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; } } 

我有同样的/类似的问题。 在稍微不同的背景下给出更明确的答案:

我有以下方法产生错误“com.google.gson.internal.LinkedTreeMap无法转换为MyType”:

 /** * Reads a LinkedHashMap from the specified parcel. * * @param  * The type of the key. * @param  * The type of the value. * @param in * The in parcel. * @return Returns an instance of linked hash map or null. */ public static  LinkedHashMap readLinkedHashMap(Parcel in) { Gson gson = JsonHelper.getGsonInstance(); String content = in.readString(); LinkedHashMap result = gson.fromJson(content, new TypeToken>(){}.getType()); return result; } 

我想要一种简单的通用方法来读/写链接的hashmap。 上面的解决方案不起作用,因为据我所知,编译后,带有TKey和TValue的TypeToken的类型信息将丢失。 这就是问题所在。 如果您将代码更改为以下示例,那么它可以正常工作,因为现在我们明确定义了类型标记。 我不太了解java,我理解为什么在这种情况下可以在运行时读取类型信息。

 /** * Reads a LinkedHashMap from the specified parcel. * * @param  * The type of the key. * @param  * The type of the value. * @param in * The in parcel. * @return Returns an instance of linked hash map or null. */ public static  LinkedHashMap readLinkedHashMap(Parcel in, TypeToken> typeToken) { Gson gson = JsonHelper.getGsonInstance(); Type type = typeToken.getType(); String content = in.readString(); LinkedHashMap result = gson.fromJson(content, type); return result; } 

现在你可以调用上面的函数:

 readLinkedHashMap(in, new TypeToken>(){}); 

旁注1:当写入链接的哈希映射时,您根本不需要指定任何类型的令牌。 toJson(地图)就足够了。

旁注2(对于我遇到的问题):默认情况下,gson使用toString()来序列化密钥。 如果为密钥类型注册类型适配器(可能是更复杂的类型),则在序列化时,但在反序列化时不应用此类型适配器。 这导致不一致且因此失败的过程。 以下选项激活复杂的映射键序列化 。

 gsonBuilder.enableComplexMapKeySerialization() 

终于明白了!

问题是:

new TypeToken >(){}。getType();

返回JSONObject 的类型,而不是扩展Repository的子类的特定实体(例如,UserRepository扩展了Repository )。

诀窍是创建一个抽象方法来强制子类设置反序列化的类型。

总之,如果你得到这个错误,请确保你有正确的类类型(如果你使用子类,请确保它返回你的子类的类型而不是超类)。