天天看點

24.transient關鍵字詳解24.transient關鍵字詳解

24.transient關鍵字詳解

目錄

1 接口 Serializable

2 序列化與反序列化

3 transient關鍵字

  3.1 JDK中transient關鍵字應用舉例

  3.2 對象序列化transient關鍵字應用舉例

我在自己的項目中很少使用transient關鍵字。這個關鍵字的作用是和序列化相關的。JDK的源碼中ArrayList類用到了transient關鍵字.整理一下這個關鍵字相關的内容.

1 接口 Serializable

提到transient關鍵字之前需要先了解Serializable接口. Serializable接口 JDK1.6文檔. java.io.Serializable接口中沒有任何方法或者字段,僅用于辨別可序列化的語義。類通過實作接口以啟用其序列化功能。未實作此接口的類将無法使其任何狀态序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。

2 序列化與反序列化

序列化是指将對象的狀态資訊轉換為可以存儲或傳輸的形式的過程。簡單了解為,對象轉換為位元組序列的過程稱為對象的序列化;把位元組序列恢複為對象的過程稱為對象的反序列化。

3 transient關鍵字

這個類實作了Serilizable接口,這個類的所有屬性和方法都會自動序列化。

在實際開發過程中,這個類的有些屬性需要序列化,而其他屬性不需要被序列化。 例如:一些敏感資訊(如密碼,銀行卡号等),為了安全起見,不希望在網絡操作(主要涉及到序列化操作,本地序列化緩存也适用)中被傳輸,這些資訊對應的變量就可以加上transient關鍵字。換句話說,這個字段的生命周期僅存于調用者的記憶體中而不會寫到磁盤裡持久化。

實作Serilizable接口,将不需要序列化的屬性前添加關鍵字transient,序列化對象的時候,這個屬性就不會序列化到指定的目的地中。

3.1 JDK中transient關鍵字應用舉例

ArrayList源碼中應用到了transient關鍵字。

elementData是一個緩存數組,通常會預留一些容量,等容量不足時再擴充。擴充空間超過實際資料長度的備援部分,沒有實際意義。不需要進行序列化。是以ArrayList的設計者将elementData設計為transient,然後在writeObject方法中隻序列化了實際存儲的那些元素,而不是整個數組。

3.2 對象序列化transient關鍵字應用舉例

  • 實作步驟: 1.建立一個簡單的類,定義幾個成員變量,其中的一個變量設定為transient關鍵字修飾。 2.建立一個位元組輸出流,将這個對象序列化,輸出到位元組數組中。 3.建立一個輸入流,從這個位元組數組反序列化,執行個體化這個對象。 4.輸出這個對象的屬性,檢視有transient關鍵字修飾修飾的變量,和沒有這個關鍵詞修飾的變量的差別。
  • 示例代碼
package com.dashidan.lesson24;

import java.io.*;

/**
 * 大屎蛋教程網-dashidan.com
 * Java教程基礎篇:  24.transient關鍵字詳解
 * 2018/5/26
 */
public class Demo1 {

    static int id = 100;
    static String name = "大屎蛋";
    static String url = "http://dashidan.com";
    static String weather = "晴朗";

    public static void main(String[] args) {

        /** 建立測試對象*/
        TestObject testObject = new TestObject(id, name, url, weather);
        try {
            /** 将對象序列化,輸出到byte[]中*/
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
            outputStream.writeObject(testObject);
            outputStream.close();
            byte[] bytes = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.close();

            /** 将byte[]位元組反序列化,轉化為對象*/
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
            TestObject obj = (TestObject) inputStream.readObject();
            inputStream.close();
            byteArrayInputStream.close();

            /** 輸出運作結果*/
            System.out.println(obj.getId());
            System.out.println(obj.getName());
            System.out.println(obj.getUrl());
            System.out.println(obj.getWeather());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}


/**
 * 實作Serializable接口的測試類,其中weather屬性被定義transient
 */
class TestObject implements Serializable {

    int id;
    String name;
    String url;
    transient String weather;

    public TestObject(int id, String name, String url, String weather) {
        this.id = id;
        this.name = name;
        this.url = url;
        this.weather = weather;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getUrl() {
        return url;
    }

    public String getWeather() {
        return weather;
    }
}
           

輸出結果

100
大屎蛋
http://dashidan.com
null
           

從這個輸出結果可以看出由transient修飾的變量輸出為null,說明沒有序列化。

将這個關鍵字删除,再運作一遍,輸出結果:

100
大屎蛋
http://dashidan.com
晴朗
           

移除這個關鍵字以後,輸出結果中就能反序列出這個屬性的值。通過這個簡單的例子可以了解transient關鍵字在序列化與反序列化中的作用。

轉載請保留 原文連結. 相關文章 :

https://dashidan.com/article/java/index.html