Gson:java.lang.StackOverflowError: null

后端 未结 1 1296
灰色年华
灰色年华 2021-01-16 03:24

i have a class Delete which i want to convert it into json using Gson library but when i convert it it throws exception of java.lang.StackOverflowError: null he

相关标签:
1条回答
  • 2021-01-16 03:39

    The issue is that the bytecode of a Scala Enumeration contains a collection of the possible values - each of which is an instance of the enumeration.

    For example, if we run javap CoinFaces on:

    object CoinFaces extends Enumeration {
      type CoinFaces = Value
      val Heads, Tails = Value
    }
    

    we can see that the Java disassembly contains static field values of type Enumeration$Value:

    public final class CoinFaces {
      public static scala.Enumeration$Value Tails();
      public static scala.Enumeration$Value Heads();
      public static scala.Enumeration$ValueSet$ ValueSet();
      public static scala.Enumeration$ValueOrdering$ ValueOrdering();
      public static scala.Enumeration$Value withName(java.lang.String);
      public static scala.Enumeration$Value apply(int);
      public static int maxId();
      public static scala.Enumeration$ValueSet values();
      public static java.lang.String toString();
    }
    

    This means that from Java, all Scala enumerations contains cyclical references. The easiest solution to this is to annotate such fields as @transient (https://stackoverflow.com/a/14489534/323177). Unfortunately, since we cannot annotate the generated bytecode for your custom Scala Enumeration, the solution is to create a custom GSON serializer that manually serializes the enumeration value as a String.

    import com.google.gson.JsonElement;
    import com.google.gson.JsonPrimitive;
    import com.google.gson.JsonSerializationContext;
    import com.google.gson.JsonSerializer;
    import scala.Enumeration;
    
    import java.lang.reflect.Type;
    
    // Scala enumerations are static Java classes with values of type `Enumeration.Value`
    public class GsonScalaEnumerationSerializer implements JsonSerializer<Enumeration.Value> {
      @Override
      public JsonElement serialize(final Enumeration.Value enumValue,
                                   final Type typeOfEnum,
                                   final JsonSerializationContext context) {
    
        return new JsonPrimitive(enumValue.toString());
      }
    }
    

    Then register this as a type adapter during construction of your Gson object and this will then serialise the Enumeration value.

    Gson gson = new GsonBuilder()
        .registerTypeAdapter(Enumeration.Value.class, new GsonScalaEnumerationSerializer())
        .create();
    
    0 讨论(0)
提交回复
热议问题