GSON converts to LinkedHashMap instead of my object
gson, java
Solution
I had the same / a similar problem. To give a more clear answer in a slightly different context:
I had following Method which produced the error "com.google.gson.internal.LinkedTreeMap cannot be cast to MyType":
/**
* 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;
}
I wanted an easy generic way to read/write linked hashmap. The above solution does not work because the type information of the TypeToken with TKey an TValue will be lost after compilation as far as i understand. And this is the problem. If you change you're code to following example, then it works, because now we explicitly define the type token. I am not so much into java that i understand why in this case it is possible to read the type information at runtime.
/**
* 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;
}
And now you would call the above function like:
readLinkedHashMap(in, new TypeToken<LinkedHashMap<UUID, MyObject>>(){});
A sidenote 1: When writign the linked hash map, you do not need to specify any type token at all. toJson(map) is sufficient.
A sidenote 2 (to a problem which I had): By default gson uses toString() to serialize the key. If you register a type adapter for the key type which is maybe a more complex type, then this type adapter is not applied when serializing, but when deserializing. This leads to a non consistent and therefore failing process. Following options activates complex map key serialization.
gsonBuilder.enableComplexMapKeySerialization()
Problem
I have this snippet of code: ``` 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()) ; } } ``` When I try to do the foreach my entities object is no longer of type Entity but LinkedHashMap and I get this exception: java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.tranca.bookstore.domain.shared.BaseObject Here is the JSONObject class(created by me) ``` 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++; } ``` } maybe the base object is relevant so I will put the code here: ``` 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; } } ```