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、序列化对比:

 

posted @   小菜变大鸟  阅读(336)  评论(0)    收藏  举报
(评论功能已被禁用)
编辑推荐:
· 一次 .NET 性能优化之旅:将 GC 压力降低 99%
· MySQL索引完全指南:让你的查询速度飞起来
· 一个字符串替换引发的性能血案:正则回溯与救赎之路
· 为什么说方法的参数最好不要超过4个?
· C#.Net 筑基-优雅 LINQ 的查询艺术
阅读排行:
· 一次 .NET 性能优化之旅:将 GC 压力降低 99%
· 32岁入行STM32迟吗?
· C#.Net筑基-泛型T & 协变逆变
· 花150元,我用 AI 做出了千万播放的爆款视频!保姆级教程+完整提示词
· 【EF Core】DbContext是如何识别出实体集合的
点击右上角即可分享
微信分享提示