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