【編程思想】03 編寫高質量代碼、Java 開發中通用的方法和準則

11、養成良好習慣,顯式聲明UID

  1. 介紹

a: 類實現Serializable接口的目的是爲了可持久化,比如網絡傳輸或本地存儲,爲系統的分佈和異構部署提供先決支持條件。

b:JVM在反序列化時,會比較數據流中的serialVersionUID與類的serialVersionUID是否相同,如果相同,則認爲類沒有發生改變,可以把數據流load爲實例對象;如果不相同,對不起,我JVM不幹了,拋個異常InvalidClassException給你瞧瞧。這是一個非常好的校驗機制,可以保證一個對象即使在網絡或磁盤中“滾過”一次,仍能做到“出淤泥而不染”,完美地實現類的一致性。

c: 反序列化實現了版本向上兼容的功能,使用V1.0版本的應用訪問了一個V2.0版本的對象,這無疑提高了代碼的健壯性。我們在編寫序列化類代碼時,隨手加上serialVersionUID字段,也不會給我們帶來太多的工作量,但它卻可以在關鍵時候發揮異乎尋常的作用。

d: 顯式聲明serialVersionUID可以避免對象不一致,但儘量不要以這種方式向JVM“撒謊”。

  1. 被序列化類
package com.hao.test.Serialization;

import lombok.Data;

import java.io.Serializable;

/**
 * @author haoxiansheng
 */
@Data
public class Person implements Serializable {
    private static final long seriaVersionUID=2610414093143345504L;
    private String name;

    //private Integer age;
}

  1. 生產者
package com.hao.test.Serialization;

/**
 * @author haoxiansheng
 */
public class Producer {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("zhangsan");
        //person.setAge(99);
        // 序列化保存到磁盤
        SerializationUtils.writeObject(person);
    }
}

  1. 消費者
package com.hao.test.Serialization;

import lombok.extern.slf4j.Slf4j;

/**
 * @author haoxiansheng
 */
@Slf4j
public class Consumer {
    public static void main(String[] args) {
        // 反序列化
        Person p = (Person)SerializationUtils.readObject();
        log.info("p=>{}",p);
    }
}

  1. 序列化工具類
package com.hao.test.Serialization;

import java.io.*;

/**
 * @author haoxiansheng
 */
public class SerializationUtils {
    private static String FILE_NAME = "/Users/haoxiansheng/Downloads/Spring-Family/flameboy/src/main/resources/doc/obj.bin";

    // 序列化
    public static void writeObject(Serializable serializable) {
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(FILE_NAME));
            outputStream.writeObject(serializable);
            outputStream.close();
        } catch (IOException e) {

        }
    }

    public static Object readObject() {
        Object object = null;
        // 反序列化
        try {
            ObjectInput input = new ObjectInputStream(new FileInputStream(FILE_NAME));
            object = input.readObject();
            input.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章