成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:Transient關鍵字修飾的變量當真不可序列化?

開發 前端
通過上面的學習,我們知道了在Java的序列化中有 Serializable、Externalizable這兩個接口,前者沒有任何方法,只是一個標識,而后者作為子類,提供了必須重寫的方法,用以自定義序列化設計。

一、寫在開頭

在這篇文章中記錄一下之前自己面試時學到的東西,是關于transient關鍵字的,當時面試官問我IO的相關問題,基本上全答出來了,關于如何不序列化對象中某個字段時,我果斷的選擇了static和transient,但面試官緊接著問了我:“transient關鍵字修飾的變量當真不可序列化嗎?”,這個問題直接給我整不確定了,因為以當時的知識儲備,這個問題確實不知道,最終虛心的向這位面試官請教,他告訴了我答案。

雖然那場面試我還是通過了,但是我沒去,哈哈!不過還是挺感謝那個耐心的面試官的,隨口的一個問題,其實大部分面試官是不會負責給你解答的。

二、案例測試

今天,我們就花一點時間,來把這個問題梳理一遍。我們先寫一個測試類,去看一下static和transient關鍵字修飾的字段,在序列化過程中的表現:

public class Test {
    public static void main(String[] args) throws IOException {
        //初始化對象信息
        Person person = new Person();
        person.setName("JavaBuild");
        person.setAge(30);
        System.out.println(person.getName()+" "+person.getAge());

        //序列化過程
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("E:\\person.txt"));) {
            objectOutputStream.writeObject(person);
        } catch (IOException e) {
            e.printStackTrace();
        }
        person.par1 = "序列化后靜態字段";
        //反序列化過程
        try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:\\person.txt"));) {
            Person p = (Person) objectInputStream.readObject();
            System.out.println(p);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}
class Person implements Serializable{

    private static final long serialVersionUID = 8711922740433840551L;
    private String name;
    private int age;

    public static String par1 = "靜態字段";
    transient String par2 = "臨時字段";
    transient int high = 175;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", par1=" + par1 +
                ", high=" + high +
                ", par2='" + par2 + '\'' +
                '}';
    }
}

輸出:

JavaBuild 30
Person{name='JavaBuild', age=30, par1=序列化后靜態字段, high=0, par2='null'}

通過打印結果我們可以看到,static修飾的字段,并沒有參與序列化,讀取到了后面修改的值;transient關鍵字修飾的字段也沒參與,而且在反序列化過程中,會被重置為默認值,例如基本數據類型為 0,引用類型為 null。至于原因我們在這里不展開了,上一篇文章里已經提到,大家可以去看看。

三、直入主題

我們再回過頭來看看起初的問題:transient 修飾的字段真的不能被序列化?至少通過Serializable接口標示的序列化方式里,transient字段時不可被序列化的,因為在序列化過程中調用的ObjectStreamClass對象,里面有個方法為getDefaultSerialFields(),已經明確的標記出了transient修飾符不可被序列化!

圖片圖片

那我們怎么辦呢?

Externalizable接口:

其實呀,除了 Serializable 之外,Java 還提供了一個序列化接口 Externalizable,它是Serializable的子接口,使用 Externalizable 進行反序列化的時候,會調用被序列化類的無參構造方法去創建一個新的對象,然后再將被保存對象的字段值復制過去;實現Externalizable接口時,必須重寫其中的writeExternal() 和 readExternal()方法,我們通過這兩個方法進行序列化的設計與讀取。

圖片圖片

適應場景: 因為Externalizable接口擁有著更高的序列化控制能力,所以在序列化過程中,我們需要對一些敏感信息進行加密處理時,它的作用就會體現啦。

我們使用這個接口進行序列化嘗試,并且使用transient關鍵字修飾字段,看一下結果:

public class Test implements Externalizable {

    private transient String text = "我可以被序列化!!!";

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        //序列化
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("E:\\transient.txt"));
        out.writeObject(test);
        //反序列化
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("E:\\transient.txt"));
        test = (Test)in.readObject();
        System.out.println(test.text);
        //關閉流
        out.close();
        in.close();
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(text);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        text = (String) in.readObject();
    }
}

輸出:

我可以被序列化!!!

數據成功被序列化到txt文件中,并成功的反序列化讀取到程序中了!即便text被transient修飾著!

四、總結

通過上面的學習,我們知道了在Java的序列化中有 Serializable、Externalizable這兩個接口,前者沒有任何方法,只是一個標識,而后者作為子類,提供了必須重寫的方法,用以自定義序列化設計。此外,transient 關鍵字只能修飾字段,而不能修飾方法和類,需要注意。

責任編輯:武曉燕 來源: JavaBuild888
相關推薦

2018-01-19 10:43:06

Java面試官volatile關鍵字

2020-12-04 06:27:04

序列化面試官Java

2022-02-21 17:24:18

序列化對象存儲

2022-06-09 11:20:44

volatile關鍵字

2024-03-28 10:40:43

javanew關鍵字

2019-08-26 11:29:27

Java序列化數據

2015-04-13 17:15:11

模塊化UPS華為

2024-08-08 16:53:17

2011-06-01 15:05:02

序列化反序列化

2022-08-06 08:41:18

序列化反序列化Hessian

2015-08-13 10:29:12

面試面試官

2022-01-05 08:56:20

Vue修飾符面試

2024-03-25 11:03:38

Vue修飾符lazy

2018-03-19 10:20:23

Java序列化反序列化

2009-12-03 19:06:44

PHP關鍵字globa

2009-12-10 13:31:20

PHP self關鍵字

2009-06-14 22:01:27

Java對象序列化反序列化

2009-08-24 17:14:08

C#序列化

2022-05-23 08:43:02

BigIntJavaScript內置對象

2023-10-26 08:12:37

Java變量類型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区二区三区在线观看免费 | 日韩精品一区二区三区 | 免费毛片网 | 欧洲成人午夜免费大片 | 国产成人精品一区二区三区网站观看 | 欧美中文字幕 | 亚洲精品一区国语对白 | 毛片黄片免费看 | 国产一区二区精品在线观看 | 国产精品免费看 | 在线观看的av | 九九热精品视频 | 久久9精品 | 精品久久久久久久 | 日韩在线高清 | 亚洲免费片 | 亚洲最新网址 | 欧美成人免费在线视频 | 精品久久久久久久久久 | 亚洲精品久久久久久久久久吃药 | 99精品欧美一区二区三区 | 日韩一区二区福利视频 | 中文成人在线 | 国产一级视频 | 91嫩草精品| 免费黄色的网站 | 久久久久国产一级毛片高清网站 | 91久久久久 | av片在线观看 | 高清国产午夜精品久久久久久 | 天天色综 | 精品一区二区三区四区五区 | 成人精品一区二区三区中文字幕 | 在线一级片 | 日韩成人高清在线 | 成人精品一区二区三区 | 亚洲视频一| 一区二区高清 | 国产精品久久久久久吹潮日韩动画 | 给我免费的视频在线观看 | 国产中文字幕亚洲 |