问题描述
我有这段代码:
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());
$ / code>
当我尝试执行foreach时,我的实体对象是不再是实体类型,但LinkedHashMap,我得到这个异常:java.lang.ClassCastException:java.util.LinkedHashMap不能转换为com.tranca.bookstore.domain.shared.BaseObject
这里是JSONObject类(由我创建)
public class JSONObject< Entity> {
私人列表<实体> entities = new ArrayList< Entity>();
private long lastId = -1;
public List< Entity> getEntities(){
返回实体;
}
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 {
保护长ID =(长)-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;
}
}
我有类似的问题。在稍微不同的上下文中给出更明确的答案:
我有下面的Method产生错误com.google.gson.internal.LinkedTreeMap不能转换为MyType :
/ **
*从指定宗地读取一个LinkedHashMap。
*
* @param< TKey>
*密钥的类型。
* @param< TValue>
*值的类型。
* @param in
*包裹内。
* @return返回链接哈希映射的实例或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());
返回结果;
}
我想要一个简单的通用方法来读/写链接的hashmap。上述解决方案不起作用,因为根据我的理解,编译后会丢失带有TKey和TValue的TypeToken的类型信息。这就是问题所在。如果您将代码更改为以下示例,那么它就可以工作,因为现在我们明确定义了类型标记。我没有那么多的java,我明白为什么在这种情况下可以在运行时读取类型信息。
/ **
*从指定宗地读取一个LinkedHashMap。
*
* @param< TKey>
*密钥的类型。
* @param< TValue>
*值的类型。
* @param in
*包裹内。
* @return返回链接哈希映射的实例或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);
返回结果;
}
现在你可以调用上面的函数了:
readLinkedHashMap(in,new TypeToken< LinkedHashMap< UUID,MyObject>>(){});
旁注1:当写入链接哈希映射时,您不需要在所有。 toJson(map)就足够了。
附注2(对于我有的问题):默认情况下,gson使用toString()序列化键。如果您为可能是更复杂类型的密钥类型注册类型适配器,则在序列化时不应用此类型适配器,但在反序列化时应用此类适配器。这导致了一个不一致的,因此失败的过程。以下选项激活复杂地图
gsonBuilder.enableComplexMapKeySerialization()
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;
}
}
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()
这篇关于GSON转换为LinkedHashMap而不是我的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!