欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android?Gson基本用法學(xué)習(xí)

 更新時間:2021年12月12日 15:31:40   作者:chenrenxiang  
這篇文章介紹了Android?Gson的基本用法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

Gson是谷歌官方推出的支持 JSON -- Java Object 相互轉(zhuǎn)換的 Java序列化/反序列化 庫,之前由于沒有用過,所以學(xué)習(xí)一下。

1. 導(dǎo)入Android Studio工程

dependencies {
    implementation 'com.google.code.gson:gson:2.8.4'
}

2. 簡單的 Java Object 序列化/反序列化

序列化

假如有一個User類,擁有 name, email, age, isDeveloper 四個屬性,如下:

User userObject = new User(  
    "Norman", 
    "norman@futurestud.io", 
    26, 
    true
);

使用Gson將它序列化:

Gson gson = new Gson();
String userJson = gson.toJson(userObject);

得到的結(jié)果如下:

{
	"isDeveloper":true,
	"name":"Norman",
	"age":26,
	"email":"norman@futurestud.io"
}

反序列化

先定義一段JSON字符串

String userJson = "{'isDeveloper':false,'name':'xiaoqiang','age':26,'email':'578570174@qq.com'}";

Gson反序列化

User user = gson.fromJson(userJson, User.class);

debug一下,查看結(jié)果

反序列化成功!

3. 嵌套 Java Object 的序列化/反序列化

也就是說,一個類里面還包含有其它類。比如User類里面還有個用戶地址UserAddress類,JSON結(jié)構(gòu)如下:

{
    "age": 26,
    "email": "578570174@qq.com",
    "isDeveloper": true,
    "name": "chenrenxiang",

    "userAddress": {
        "city": "Magdeburg",
        "country": "Germany",
        "houseNumber": "42A",
        "street": "Main Street"
    }
}

那么這種Java Object該如何序列化/反序列化呢?和上面一樣。也就是說和 2 里面介紹的方法一樣

4. Array 和 List 的序列化/反序列化

序列化

序列化和前面介紹的方法是一樣的

反序列化

那就有些不同了,不然也不用分開寫。

1 Array的反序列化

先假設(shè)有一個name數(shù)組,定義JSON格式如下:

String namesJson = "['xiaoqiang','chenrenxiang','hahaha']";

然后使用Gson去反序列化它:

Gson gson = new Gson();
String[] nameArray = gson.fromJson(namesJson, String[].class);

得到的nameArray如下:

其實(shí)這和 2 里面介紹的反序列化方法仍然是一樣的??梢钥吹?,Gson的反序列化都是調(diào)用 Gson.fromJson(...)方法,傳入JSON字符串,以及這段JSON字符串對應(yīng)的Object類型。

2 List的反序列化

String userJson = "[{'isDeveloper':false,'name':'xiaoqiang','age':26,'email':'578570174@qq.com'},{'isDeveloper':true,'name':'xiaoqiang123','age':27,'email':'578570174@gmail.com'}]";

Gson gson = new Gson();
Type userListType = new TypeToken<ArrayList<User>>(){}.getType();

List<User> userList = gson.fromJson(userJson, userListType); 

對于List,反序列化時必須提供它的Type,通過Gson提供的TypeToken<T>.getType()方法可以定義當(dāng)前List的Type。反序列化后結(jié)果如下:

那么,如果一個Java Object里包含List類型的變量,該如何反序列化這個Object呢?答案是,和 2 一樣就行了,無需為其內(nèi)部的List提供Type。

5. Map 和 Set 的序列化/反序列化

Map我平時用的較多,Set用的就很少了,它們的序列化/反序列化方法和List都是一樣的,反序列化的時候需要提供Type

6. 變量值為null時的序列化/反序列化

仍然以User類為例,如果一個User對象,里面的某個值為null,那么其序列化出來后的結(jié)果會是什么樣的呢?

先看序列化,我們先初始化一個User對象,并把其中的email變量賦值為null,再用Gson來序列化它,如下:

    User user = new User(true, "chenrenxiang", 27, null);
    Gson gson = new Gson();
    String userJson = gson.toJson(user);

debug一下,得到結(jié)果如下:

可見,當(dāng)某個變量值為null時,Gson在序列化的時候直接把這個變量忽略了。

再來看下反序列化, 先定義一段JSON字符串,只給它一個變量值name,用User類來反序列化它,看得到的結(jié)果會是什么。

   String userJson = "{'name':'xiaoqiang'}";
   Gson gson = new Gson();
   User user = gson.fromJson(userJson, User.class);

對于JSON字符串里沒有的變量,Gson在反序列化時會給它一個默認(rèn)值,int類型默認(rèn)為0,bool類型默認(rèn)為false,String類型默認(rèn)為null。

有人不禁要問了,如果JSON字符串里某個變量的值為null,反序列化后的結(jié)果會是什么呢?我測試過了,和沒有的結(jié)果是一樣的。

7. 控制序列化/反序列化 的變量名稱

仍然以User對象為例,目前User對象里有四個變量name, ageemail, isDeveloper。假如,某一天,JSON字符串的變量名name變成了fullName,無需緊張,我們不用把User類里的變量name改為fullName,然后把它的getset方法都改了,然后把用到get/set方法的地方全改過來。只需要用Gson提供的注解方法@SerializedName就行了,如下:

public class User {
    private boolean isDeveloper;
    @SerializedName("fullName")
    private String name;
    private int age;
    private String email;
    ...
}

這樣雖然JSON字符串里的變量名為fullName,但是反序列化后fullName的值會映射給name。同樣,把一個User對象序列化,變量name會自動轉(zhuǎn)換為fullName

然而現(xiàn)實(shí)遠(yuǎn)比想象中復(fù)雜,這個JSON有時候傳的是fullName,有時候傳的是name,這時該怎么辦呢? 不用擔(dān)心,@SerializedName 接受兩個參數(shù),valuealternate ,顧名思義,alternate 是備選變量名,比如下面這段代碼:

public class User {
    private boolean isDeveloper;
    @SerializedName(value = "name", alternate = "fullName")
    private String name;
    private int age;
    private String email;
    ...
}

如果JSON傳的是name,那么就用name的值,如果傳的是fullName,那么就用fullName的值。需要注意的是,alternate只是反序列化JSON的一個備選變量名,它不會影響序列化,User對象序列化后,會使用value定義的名稱為變量名。

又想到有一個問題,在定義了value和alternate的情況下,假如JSON同時傳來了name和fullName,User的name變量會接受哪個值呢? 經(jīng)過測試,它會都接受。這樣也是很合理的,因?yàn)镚son會對JSON中的變量一個一個地去解析,既然它可以接受name,也可以接受fullName,那么當(dāng)同時傳來這兩個變量時,它就會分別把它們解析出來,并把值賦給User對象中的name變量。那么,name變量的值就會是后解析的那個JSON變量的值,因?yàn)樗鼤亚耙粋€值覆蓋掉。

8. 序列化/反序列化過程中忽略某些變量

也許會出現(xiàn)這樣的需求,在將某個對象序列化時,對象中的某些變量是不需要的。有可能在反序列化某個JSON字符串時,某些變量的值也是不需要的。這時就可以使用Gson提供的@Expose注解方法。使用方法如下:

public class User {  
    @Expose()
    String name; // 參與序列化/反序列化

    @Expose(serialize = false, deserialize = false)
    String email; // 不參與序列化,也不參與反序列化

    @Expose(serialize = false)
    int age; // 只參與反序列化

    @Expose(deserialize = false)
    boolean isDeveloper; // 只參與序列化
}

使用這個方法,可以非常靈活地控制對象的某個/某些變量參不參與序列化/反序列化。

然而! 要使用這個注解來控制序列化/反序列化,就不能使用默認(rèn)的Gson對象,新建Gson對象的方法如下:

GsonBuilder builder = new GsonBuilder();  
builder.excludeFieldsWithoutExposeAnnotation();  
Gson gson = builder.create(); 

注意:使用以上方式構(gòu)建的Gson,在序列化/反序列化對象時,會排除所有沒有添加@Expose注解的字段。

另一個選擇,transient關(guān)鍵字 ,使用這個關(guān)鍵字,可以直接讓變量不參與序列化/反序列化,如下:

public class User {  
    String name;
    String email;
    int age;
    boolean transient isDeveloper; //不參與序列化/反序列化
}

當(dāng)然,使用默認(rèn)的Gson對象就可以。

以上所述是小編給大家介紹的Android?Gson基本用法,希望對大家有所幫助。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評論