Gson和Fastjson序列学习
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、序列化对比:
【推荐】FlashTable:表单开发界的极速跑车,让你的开发效率一路狂飙
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一次 .NET 性能优化之旅:将 GC 压力降低 99%
· MySQL索引完全指南:让你的查询速度飞起来
· 一个字符串替换引发的性能血案:正则回溯与救赎之路
· 为什么说方法的参数最好不要超过4个?
· C#.Net 筑基-优雅 LINQ 的查询艺术
· 一次 .NET 性能优化之旅:将 GC 压力降低 99%
· 32岁入行STM32迟吗?
· C#.Net筑基-泛型T & 协变逆变
· 花150元,我用 AI 做出了千万播放的爆款视频!保姆级教程+完整提示词
· 【EF Core】DbContext是如何识别出实体集合的