2013-02-25 21 views
2

是一个“动物”我有一个具体基类,Animal,和几个子类DogCat等。序列化“狗”,如果它使用GSON

DogCat的细节是不相关的,所以我想序列化这些子类的实例,就像序列化Animal s一样。

有很多这样的小类,所以我宁愿一个解决方案,没有列出他们全部。基于instanceof Animal的东西将是理想的。

+0

请告诉我的背景?你是否想在所有情况下将这些子类序列化为它们的父类?或者,您是否在运行时确定何时何地忽略子类类型,并将其序列化为父类? – Perception 2013-02-25 20:38:09

+0

在所有情况下都相同。 (“编译时间的决定”) – aioobe 2013-02-25 20:39:00

+0

我知道在任何情况下都无法通过编译时决策来完成。 [Jackson](http://jackson.codehaus.org/)可以通过它的'@JsonSerialize(as)'注释来实现,但是在Gson中没有等价的(我知道的)。最好的办法是通过GsonBuilder注册一个类型的heirarchy适配器,以覆盖父类的序列化行为。这将在逐个解析器的基础上进行。 – Perception 2013-02-25 20:58:44

回答

1

(来自于完整的答案评论移动)

如果从未想要序列化的子类为那些subsclasses,只为母体,只是标志着在子类中的所有领域transient - 默认Gson韩元” t序列化它们。

如果您希望能够做到这一点,请使用Gson @Expose注释标记父类中的所有字段。然后,当你序列化你可以选择使用哪种方式序列化:

Gson gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 

当你只希望在JSON中表示的父类。

+0

这似乎是一个“一次性”解决方案。我确实有一个typeHierarchyAdapter。 (在这个层次结构中'Animal'不是我的根类。)我打赌'Dog'的实例在序列化中将有一个'type =“Dog”字段。这不会被反序列化结束。尽管如此,我仍会试一试。 – aioobe 2013-02-25 21:54:01

+0

是的,这使得它更复杂。您可以进一步定义自己的'ExclusionStrategy'并使用您自己的自定义注释。 http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/ExclusionStrategy.html - 无论哪种方式都有点麻烦。 – 2013-02-25 21:56:22

+0

好点。现在我正在考虑明确列出所有子类,并让它们共享一个将它们视为“Animal”的JsonSerializer。 : - / – aioobe 2013-02-25 22:06:27

0

我的天真黑客,我编码只是为了好玩(但是如果演出不是问题,值得一试)。

public static void main(String[] args) { 
    ArrayList<Animal> al = new ArrayList<Animal>(); 
    al.add(new Dog()); 
    al.add(new Fish()); 
    al.add(new Dog()); 

    String originalString = new Gson().toJson(al); 
    System.out.println(originalString); 

    ArrayList<Animal> a = new ArrayList<Animal>(); 
    Type listType = new TypeToken<List<Animal>>() {}.getType(); 

    a = new Gson().fromJson(originalString, listType); 

    String newString = new Gson().toJson(a); 

    System.out.println(newString); 

} 

结果:

Original string: [{"feet":4,"name":"Dog"},{"canSwim":true,"name":"fish"},{"feet":4,"name":"Dog"}] 
New string: [{"name":"Dog"},{"name":"fish"},{"name":"Dog"}]