1、Gson序列化(只关注Field):
可以看出使用GSON序列化,没有getter和setter是可以的,只要有Field就可以,查看源代码可以知道Gson使用Field[] fields = raw.getDeclaredFields()来获取需要序列化的字段;
getDeclaredFields可以获取对象的所有字段,但是GSON排除了被transient和static修饰的字段Field
getDeclaredFields本身不能获取父类的字段,但是GSON内部处理是一直循环到Object对象,最终会序列化出该类及所有父类中的Field
class Animal { private String name_a; private Integer age_a; public Animal(String name, Integer age) { this.name_a = name; this.age_a = age; } public String toString() { return "Animal [name_a=" + name_a + ", age_a=" + age_a + "]"; } } class Person extends Animal { private String name_p; private Integer age_p; public Person(String name, Integer age) { super(name, age); this.name_p = name; this.age_p = age; } public String toString() { return "Person [name=" + name_p + ", age=" + age_p + "]"; } }
测试代码:
Person person = new Person("轩辕", 10); Gson gson = new Gson(); String json = gson.toJson(person); System.out.println(json);
输出结果:{"name_p":"轩辕","age_p":10,"name_a":"轩辕","age_a":10}
2、Fastjson序列化(关注Method和Field):
class Animal { private String name_a; private Integer age_a; public Animal(String name, Integer age) { this.name_a = name; this.age_a = age; } public String toString() { return "Animal [name_a=" + name_a + ", age_a=" + age_a + "]"; } } class Person extends Animal { private String name_p; private Integer age_p; public Person(String name, Integer age) { super(name, age); this.name_p = name; this.age_p = age; } public String getName_p() { return name_p; } public Integer getAge_p() { return age_p; } public String toString() { return "Person [name=" + name_p + ", age=" + age_p + "]"; } }
测试代码:
Person person = new Person("轩辕", 10); String json = JSON.toJSONString(person); System.out.println(json);
输出结果:{"age_p":10,"name_p":"轩辕"}
可以看出,Animal中字段没有用getter和setter封装,所以序列化不出来,因为fastjson使用getMethods来获取所有getter然后生成字段名来序列化的;
如果注释掉setter,也是可以序列化的,说明fastjson使用getMethods序列化只关注getter。
将Animal内容改为如下:
class Animal { public String name_a; public static Integer age_a; public Animal(String name, Integer age) { this.name_a = name; age_a = age; } public String toString() { return "Animal [name_a=" + name_a + ", age_a=" + age_a + "]"; } }
输出结果:{"age_p":10,"name_a":"轩辕","name_p":"轩辕"}
说明static字段不能序列化,而public修饰的Field可以序列化;说明fastjson使用getFields来获取公有成员字段(不包含static|transient修饰的字段)
一般来说真是开发很少使用public修饰Field,所以一般关注fastjson使用getter来序列化就可以了。
3、序列化忽略属性:
gson:
@Expose注解放在字段上,但要注意没有@Expose的字段才会被忽略,有@Expose的字段可以控制是否被序列化或者反序列化,其实使用transient来修饰才是最方便的,毕竟忽略的字段属于少数,
而不用忽略的每个属性都要加上@Expose注解;使用ExclusionStrategy自定义排除策略就更麻烦了。
fastjson:
由于是关注的getter方法,所以[@JSONField]注解要放在getter上
总结:gson的@Expose与transient都没有fastjson好用,既然有fastjson何必不用简单的呢?
class Animal { @Expose public String name_a; @Expose public static Integer age_a; public Animal(String name, Integer age) { this.name_a = name; age_a = age; } public Animal() { } public String toString() { return "Animal [name_a=" + name_a + ", age_a=" + age_a + "]"; } } class Person extends Animal { @Expose(deserialize = false) private String name_p; @Expose(serialize = false) private Integer age_p; public Person(String name, Integer age) { super(name, age); this.name_p = name; this.age_p = age; } public Person() { } @JSONField(deserialize = false) public String getName_p() { return name_p; } @JSONField(serialize = false) public Integer getAge_p() { return age_p; } public String toString() { return "Person [name=" + name_p + ", age=" + age_p + "]"; } }
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); String json = gson.toJson(person); System.out.println(json); person = gson.fromJson(json, Person.class);
String json = JSON.toJSONString(person); System.out.println(json); person = JSON.parseObject(json, Person.class);
4、序列化对比:
来源:https://www.cnblogs.com/xy-nb/p/json.html