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
诀窍是创建一个抽象方法来强制子类设置反序列化的类型。
总之,如果你得到这个错误,请确保你有正确的类类型(如果你使用子类,请确保它返回你的子类的类型而不是超类)。