本文介绍了GSON转换为LinkedHashMap而不是我的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这段代码:

  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而不是我的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-05 11:17