java.lang.StackOverflowError:使用gson序列化对象时为null

时间:2019-07-17 20:48:24

标签: java inheritance serialization polymorphism gson

我正在尝试使用gson将对象序列化为json文件,这是对象类:

public class EventSetMetaData {

    private ArrayList<Feature> featureMap;

    }

featureMap列表中有两种类型的特征,第一种是原始特征:

public class Feature {

    private String featureName;
    private NormalizationType normalization;
    private boolean isSelected;
    private Normalizer normalizer;

    public Feature(String featureName) {
        this.featureName = featureName;
        isSelected = true;
        this.normalization = NormalizationType.NOT_SET;
        this.normalizer = null;
    }

可能是扩展Feature类的CategoricalFeature:

public class CategoricalFeature  extends Feature {  

    private ArrayList <String> categories;

    public CategoricalFeature(String featureName, ArrayList<String> categories) {
        super(featureName);
        this.categories = categories;
    }

我试图使用在线找到的自定义适配器来解决不同类型的问题,这是该类的实现:

public class InterfaceAdapter<T>
    implements JsonSerializer<T>, JsonDeserializer<T> {

    @Override
    public final JsonElement serialize(final T object, final Type interfaceType, final JsonSerializationContext context) 
    {
        final JsonObject member = new JsonObject();

        member.addProperty("type", object.getClass().getName());

        member.add("data", context.serialize(object));

        return member;
    }

    @Override
    public final T deserialize(final JsonElement elem, final Type interfaceType, final JsonDeserializationContext context) 
            throws JsonParseException 
    {
        final JsonObject member = (JsonObject) elem;
        final JsonElement typeString = get(member, "type");
        final JsonElement data = get(member, "data");
        final Type actualType = typeForName(typeString);

        return context.deserialize(data, actualType);
    }

    private Type typeForName(final JsonElement typeElem) 
    {
        try 
        {
            return Class.forName(typeElem.getAsString());
        } 
        catch (ClassNotFoundException e) 
        {
            throw new JsonParseException(e);
        }
    }

    private JsonElement get(final JsonObject wrapper, final String memberName) 
    {
        final JsonElement elem = wrapper.get(memberName);

        if (elem == null) 
        {
            throw new JsonParseException(
                "no '" + memberName + "' member found in json file.");
        }
        return elem;
    }

}

这是im用于序列化对象的代码:

 GsonBuilder gsonBilder = new GsonBuilder();
             gsonBilder.registerTypeAdapter(CategoricalFeature.class, new InterfaceAdapter<CategoricalFeature>());

  gsonBilder.setPrettyPrinting();

    gson =gsonBilder.create();
    f = new FileWriter("MetaData.json");
    gson.toJson(eventSetMetaData, f);
    f.close();

我得到的例外是:

java.lang.StackOverflowError: null
    at com.google.gson.stream.JsonWriter.push(JsonWriter.java:354)
    at com.google.gson.stream.JsonWriter.<init>(JsonWriter.java:170)
    at com.google.gson.internal.bind.JsonTreeWriter.<init>(JsonTreeWriter.java:58)
    at com.google.gson.Gson.toJsonTree(Gson.java:492)
    at com.google.gson.Gson.toJsonTree(Gson.java:472)
    at com.google.gson.Gson$2.serialize(Gson.java:134)
    at com.tts.tts_rta_ai_stream_processor_plugin.api.utils.InterfaceAdapter.serialize(InterfaceAdapter.java:23)
    at com.google.gson.TreeTypeAdapter.write(TreeTypeAdapter.java:70)
    at com.google.gson.Gson.toJson(Gson.java:600)
    at com.google.gson.Gson.toJsonTree(Gson.java:493)
    at com.google.gson.Gson.toJsonTree(Gson.java:472)
    at com.google.gson.Gson$2.serialize(Gson.java:134)

在要素类中,normalizationType是枚举,规范化器中目前没有任何内容,有什么主意我该如何解决这个问题?谢谢您的宝贵时间!

1 个答案:

答案 0 :(得分:0)

您如何创建eventSetMetaData?我可能会猜测您从未初始化过它或类似的东西,因此它是一个空引用。

在序列化代码中,为什么不直接使用ArrayList而不使用EventSetMetaData类?

这是一个简单的工作示例,您可以将其直接插入代码中。它直接使用ArrayList而不嵌套在EventSetMetaData类中:

//Array list used to store Features for JSON
ArrayList<Feature> featureMap = new ArrayList<>();
//Add items to ArrayList
featureMap.add(new Feature("Example Feature One"));
featureMap.add(new Feature("A different feature"));

//Create GsonBuilder and set options
GsonBuilder gsonBilder = new GsonBuilder();
gsonBilder.registerTypeAdapter(CategoricalFeature.class, new InterfaceAdapter<CategoricalFeature>());
gsonBilder.setPrettyPrinting();

//Create Gson object
Gson gson =gsonBilder.create();

//Create file Writer
Writer f = new FileWriter("MetaData.json");

//Save featureMap ArrayList to file
gson.toJson(featureMap, f);

//Tidy up
f.close();

MetaData.json中的输出看起来像(显然是简化了,因为我不知道normalizationType枚举):

[   
  {
    "featureName": "Example Feature One",
    "isSelected": true   
  },   
  {
    "featureName": "A different feature",
    "isSelected": true   
  } 
]