Gson和Fastjson序列学习

吃可爱长大的小学妹 提交于 2020-01-28 13:30:39

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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!