Gson的五大注解 @SerializedName豪墅、@Expose、@Since、@Until贴膘、@JsonAdapter
1. @SerializedName
序列化為json的時候,將提供的名稱的值作為字段名略号。
//測試代碼
class MyClass {
@SerializedName("nameA")
String a;
//alternate 備用解析名稱
@SerializedName(value = "nameB", alternate = {"nameC", "nameD"})
String b;
String c;
public MyClass(String a, String b, String c) {
this.a = a;
this.b = b;
this.c = c;
}
@Override
public String toString() {
return "MyClass{" +
"a='" + a + '\'' +
", b='" + b + '\'' +
", c='" + c + '\'' +
'}';
}
}
(1)序列化
//序列化
public static void testSerializable() {
Gson gson = new Gson();
MyClass myClass = new MyClass("a", "b", "c");
String s = gson.toJson(myClass);
System.out.println("MyClass:" + s);
}
//輸出
MyClass:{"nameA":"a","nameB":"b","c":"c"}
(1)反序列化
//反序列化
public static void testDeSerializable() {
Gson gson = new Gson();
String json = "{\"nameA\":\"a\",\"nameD\":\"b\",\"c\":\"c\"}";
MyClass myClass = gson.fromJson(json, MyClass.class);
System.out.println(myClass);
}
//輸出 刑峡,全部賦值成功
MyClass{a='a', b='b', c='c'}
細(xì)心地同學(xué)發(fā)現(xiàn),反序列化的時候玄柠,字段''nameD''是在 alternate = {"nameC", "nameD"}定義的突梦,alternate英文釋義為“備用的”,也就是說羽利,序列化的時候宫患,字段一定是序列化為value的值,但是反序列化時这弧,不論json中字段是value 還是alternate 中的值都會被匹配上娃闲,此地,將nameD換位nameB和nameC也同樣會被序列化成功匾浪。
2. @Expose
序列化和反序列化時皇帮,根據(jù)serialize(序列化)和deserialize(反序列化)的值true或者false來確定是否要序列化和反序列化,默認(rèn)都是true蛋辈。
此時構(gòu)建Gson的時候不要使用Gson gson = new Gson();属拾,這樣構(gòu)建Gson對象會將該注銷無效化,也就是說加不加該注解都一樣,相當(dāng)于沒有加該注解捌年。
class User0 {
//默認(rèn)true,正常序列化和反序列化
@Expose
String name1;
//可以序列化瓢娜,不可以反序列化
@Expose(serialize = true, deserialize = false)
String name2;
//可以反序列化,不可以序列化
@Expose(serialize = false, deserialize = true)
String name3;
@Expose(serialize = false, deserialize = false)
String name4;
@Expose(serialize = true, deserialize = true)
String name5;
//不帶有Expose注解礼预,相當(dāng)于不可以正反序列化
String name6;
public User0(String name1, String name2, String name3, String name4, String name5, String name6) {
this.name1 = name1;
this.name2 = name2;
this.name3 = name3;
this.name4 = name4;
this.name5 = name5;
this.name6 = name6;
}
@Override
public String toString() {
return "User0{" +
"name1='" + name1 + '\'' +
", name2='" + name2 + '\'' +
", name3='" + name3 + '\'' +
", name4='" + name4 + '\'' +
", name5='" + name5 + '\'' +
", name6='" + name6 + '\'' +
'}';
}
}
(1)序列化
//序列化
public static void testSerializable() {
User0 user0 = new User0("1", "2", "3", "4", "5", "6");
// Gson gson = new Gson();//此時不要用該種方式
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String s = gson.toJson(user0);
System.out.println("User0:" + s);
}
輸出
User0:{"name1":"1","name2":"2","name5":"5"}
name1眠砾、name2、name5的serialize=true托酸,所以可被序列化褒颈。
(2)反序列化
public static void testDeSerializable() {
String s = "{\"name1\":\"1\",\"name2\":\"2\",\"name3\":\"3\",\"name4\":\"4\",\"name5\":\"5\"}";
// Gson gson = new Gson();
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
User0 user0 = gson.fromJson(s, User0.class);
System.out.println(user0);
}
輸出
User0{name1='1', name2='null', name3='3', name4='null', name5='5', name6='null'}
name2、name4励堡、 name6他們的deserialize=false ,不可以反序列化谷丸。如果使用GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();構(gòu)建Gson對象,不加@Expose应结,意味著該字段不能正反序列化刨疼。
3.@Since 和 @Until
@Since
代表從某個版本啟用
@Until
代表從某個版本棄用
需要結(jié)合 new GsonBuilder().setVersion(3.0).create()
使用,不要使用 new Gson();
class User1 {
//不加不影響
String name1;
//版本從1.0開始啟用
@Since(1.0)
String name2;
//從2.0開始啟用
@Since(2.0)
String name3;
//到3.0開始棄用
@Until(3.0)
String name4;
//到4.0開始棄用
@Until(4.0)
String name5;
public User1(String name1, String name2, String name3, String name4, String name5) {
this.name1 = name1;
this.name2 = name2;
this.name3 = name3;
this.name4 = name4;
this.name5 = name5;
}
@Override
public String toString() {
return "User1{" +
"name1='" + name1 + '\'' +
", name2='" + name2 + '\'' +
", name3='" + name3 + '\'' +
", name4='" + name4 + '\'' +
", name5='" + name5 + '\'' +
'}';
}
}
(1)序列化
//序列化
public static void testSerializable() {
User1 user1 = new User1("1", "2", "3", "4", "5");
// Gson gson = new Gson();
Gson gson = new GsonBuilder().setVersion(1.0).create();
String s = gson.toJson(user1);
System.out.println("User1:" + s);
}
輸出
User1:{"name1":"1","name2":"2","name4":"4","name5":"5"}
name3要到版本2.0才啟用鹅龄,其他情況可以自行測試揩慕。
(2)反序列化
public static void testDeSerializable() {
String json = "{\"name1\":\"1\",\"name2\":\"2\",\"name3\":\"3\",\"name4\":\"4\",\"name5\":\"5\"}";
// Gson gson = new Gson();
Gson gson = new GsonBuilder().setVersion(3.0).create();
User1 user1 = gson.fromJson(json, User1.class);
System.out.println(user1);
}
輸出
User1{name1='1', name2='2', name3='3', name4='null', name5='5'}
版本3.0后,name4被棄用了扮休。
4.@JsonAdapter
@JsonAdapter 是在 Gson 2.7 及以后版本才有迎卤。
@JsonAdapter(UserJsonAdapter.class)
class User2 {
String name1;
String name2;
public User2(String name1, String name2) {
this.name1 = name1;
this.name2 = name2;
}
@Override
public String toString() {
return "User2{" +
"name1='" + name1 + '\'' +
", name2='" + name2 + '\'' +
'}';
}
}
class UserJsonAdapter extends TypeAdapter<User2> {
//javabean 轉(zhuǎn)成 json
@Override
public void write(JsonWriter out, User2 value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginObject();
out.name("name1").value(value.name1);
out.name("name2").value(value.name2);
out.endObject();
}
//json 轉(zhuǎn)為 javabean
@Override
public User2 read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
in.beginObject();
in.nextName();
String name1Value = in.nextString();
in.nextName();
String name2Value = in.nextString();
in.endObject();
return new User2(name1Value, name2Value);
}
}
序列化
//序列化
public static void testSerializable() {
User2 user2 = new User2("1", "2");
Gson gson = new Gson();
String s = gson.toJson(user2);
System.out.println("User2:" + s);
}
反序列化
public static void testDeSerializable() {
String s = "{\"name1\":\"1\",\"name2\":\"2\"}";
Gson gson = new Gson();
User2 user2 = gson.fromJson(s, User2.class);
System.out.println(user2);
}
@JsonAdapter
不僅可以加在類上,也可以加在字段上玷坠,字段多的話蜗搔,就太麻煩了,具體用法也可以參考 TypeAdapter.java
八堡、JsonReader.java
樟凄、JsonWriter.java
等源碼最上面的注釋。
不想在類上加注解兄渺,也可以使用registerTypeAdapter
注冊不同,如下
Gson gson = new GsonBuilder().registerTypeAdapter(User2.class, new TypeAdapter<User2>() {
//javabean 轉(zhuǎn)成 json
@Override
public void write(JsonWriter out, User2 value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginObject();
out.name("name1").value(value.name1);
out.name("name2").value(value.name2);
out.endObject();
}
//json 轉(zhuǎn)為 javabean
@Override
public User2 read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
in.beginObject();
in.nextName();
String name1Value = in.nextString();
in.nextName();
String name2Value = in.nextString();
in.endObject();
return new User2(name1Value, name2Value);
}
}.nullSafe()).create();
完!