Gson.toJson给出了StackOverFlowError,在这种情况下如何获得正确的json? (公共静态类)

我目前有以下课程:

static final class TabInfo{ public final String tag; public final Class clss; public Bundle args; TabInfo(String _tag, Class _class, Bundle _args) { tag = _tag; clss = _class; args = _args; } } 

其中我想创建json。 为此,我使用以下代码:

  Gson gson= new Gson(); Type hmType= new TypeToken(){}.getType(); String json = gson.toJson(methodToGetAnInstanceOfTabInfoClassHere, hmType); 

当我这样做时,我得到一个java.lang.StackOverFlowError:

 E/AndroidRuntime(10353): at Java.lang.StringBuffer.append(StringBuffer.java:219) E/AndroidRuntime(10353): at java.io.StringWriter.write(StringWriter.java:147) E/AndroidRuntime(10353): at com.google.gson.stream.JsonWriter.string(JsonWriter.java:519) E/AndroidRuntime(10353): at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:387) E/AndroidRuntime(10353): at com.google.gson.stream.JsonWriter.beginObject(JsonWriter.java:300) E/AndroidRuntime(10353): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:190) E/AndroidRuntime(10353): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrap E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 

所以,我的问题是:如何让我的gson从类TabInfo创建java对象的有效json而不会得到stackoverflower错误?

顺便说一句。 你们所有人都可以看到,我之前没有问过这么多问题,所以如果你对如何改进我的问题有任何反馈意见:请告诉我!

编辑1: bundle类是标准bundle,fi:Bundle args = new Bundle(); args.putint(“someint”,1);

查看更新的堆栈跟踪…

编辑2:如果我采用TabInfo的单个实例,通过使用String.class作为参数,例如:

  TabInfo test= new TabInfo("test", String.class, new Bundle()); String result=gson.toJson(test, hmType); 

然后我得到以下stacktrace:

 E/AndroidRuntime(22068): java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: java.lang.String. Forgot to register a type adapter? E/AndroidRuntime(22068): at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:64) E/AndroidRuntime(22068): at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:61) E/AndroidRuntime(22068): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) E/AndroidRuntime(22068): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) E/AndroidRuntime(22068): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) E/AndroidRuntime(22068): at com.google.gson.Gson.toJson(Gson.java:586) E/AndroidRuntime(22068): at com.google.gson.Gson.toJson(Gson.java:565) E/AndroidRuntime(22068): at com.google.gson.Gson.toJson(Gson.java:520) 

这是否意味着我需要为可能属于TabInfo类的所有24个不同的类创建一个TypeToken? 我该如何解决这个问题?

编辑3

好的,多亏了@Zaske,我找到了解决问题第一部分的方法。 使用另一个类签名,如下所示

 static final class TabInfo{ TabInfo(String _tag, String _class, Bundle _args) { tag = _tag; clss = _class; args = _args; } } 

现在我可以让json脱离它,但是,当我尝试通过创建实际的HashMap <String,<Stack >>来实现这一点时,我又遇到了麻烦。 我在这种情况下使用的typetoken是:

  Type hmType = new TypeToken<HashMap<String, Stack>>(){}.getType(); 

那么,现在我的最后一个问题是:如何将hashmap中的一组tabinfo-stack转换为json?

编辑4以下是一些更多信息:使用的Bundle类是Android中用于提供活动和片段参数的Bundle类。 (参见http://developer.android.com/reference/android/os/Bundle.html )

如果我做

  TabInfo test= new TabInfo("test", "String", new Bundle()); //stage 1 test String result=gson.toJson(test); Log.d("new result=",result); 

然后我得到了我的Json输出(见下文)

  D/new result=(20816): {"args":{"mClassLoader":{"packages":{}},"mMap":{},"mHasFds":false,"mFdsKnown":true,"mAllowFds":true},"clss":"String","tag":"test"} 

但是,当我尝试从TabInfo类中创建堆栈的Hashmap时,它会中断(它耗尽内存……)…

正如我所说的“从class级改变”到字符串,
为了我们的读者,我允许自己在这里回答第一部分:
不要将Class用作字段,而是使用包含完整类名的String
TabInfo应如下所示:

 static final class TabInfo{ public final String tag; public final String clss; public Bundle args; TabInfo(String _tag, Class _class, Bundle _args) { tag = _tag; clss = _class.getName(); args = _args; } } 

关于第二部分:
我不知道Bundle课程是什么 – 请提供信息,
因为我不得不改变一点并写自己的课程进行实验。

人员类是:

 public class Person implements Serializable { public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public Person() { } public Person(String name, int age) { super(); this.name = name; this.age = age; } public void setAge(int age) { this.age = age; } private String name; private int age; } 

检查的主要类别是:

 public class Main { public static void main(String[] args) { Type type = new TypeToken>>(){}.getType(); Gson gson = new Gson(); HashMap> map = new HashMap>(); map.put("yair", new Stack()); map.get("yair").add(new Person("Yair",36)); String str = gson.toJson(map,type); System.out.println(str); map = gson.fromJson(str,type); String str2 = gson.toJson(map,type); System.out.println(str2); } } 

随意运行它,你会看到str和str2都打印得很好。

更新
我检查了Bundle类,发现它包含太多信息(以我的拙见),是一个简单的参数集合。
我不明白为什么在上面的问题中不能使用简单的集合。
序列化应包含尽可能少的数据
(考虑一下将序列化数据存储在某个存储设备上或通过网络发送的情况)。 因此,除非Bundle为您提供集合不具备的特殊function,否则不要使用它。
根据经验记住,你不能用Json序列化所有东西 – 有一些限制(例如递归数据类型) – 所以是的,有些情况下你必须从一种类型转换为JSON可序列化类型。
此模式也用于其他情况,我建议您阅读有关数据传输对象的更多信息