最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的序列化和反序列化使用及解讀

 更新時間:2026年02月17日 11:37:16   作者:晚夜微雨問海棠呀  
文章總結(jié)了Java中序列化和反序列化的概念,包括序列化的用途、實現(xiàn)方式和注意事項,此外,還介紹了其他幾種常見的序列化框架,如JSON序列化、ProtocolBuffers和Kryo,并給出了最佳實踐和使用場景建議

基本概念

序列化(Serialization):將對象的狀態(tài)信息轉(zhuǎn)換為可以存儲或傳輸?shù)男问剑ㄈ缱止?jié)流)的過程。

反序列化(Deserialization):從字節(jié)流中恢復(fù)對象的過程,是序列化的逆操作。

為什么需要序列化?

  1. 持久化存儲:將對象保存到文件或數(shù)據(jù)庫中
  2. 網(wǎng)絡(luò)傳輸:在網(wǎng)絡(luò)上傳輸對象(如分布式系統(tǒng)、RPC調(diào)用)
  3. 進(jìn)程間通信:在不同進(jìn)程之間傳遞對象
  4. 緩存:將對象緩存到內(nèi)存或磁盤

Java 序列化實現(xiàn)

1. 實現(xiàn) Serializable 接口

import java.io.*;

// 可序列化的類
public class Person implements Serializable {
    // 序列化版本號(強(qiáng)烈建議)
    private static final long serialVersionUID = 1L;
    
    private String name;
    private int age;
    
    // transient 關(guān)鍵字:該字段不會被序列化
    private transient String password;
    
    public Person(String name, int age, String password) {
        this.name = name;
        this.age = age;
        this.password = password;
    }
    
    // getters and setters...
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + ", password='" + password + "'}";
    }
}

2. 序列化操作

public class SerializationDemo {
    public static void serialize(Object obj, String filename) throws IOException {
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(filename))) {
            oos.writeObject(obj);
            System.out.println("對象序列化成功!");
        }
    }
    
    public static Object deserialize(String filename) throws IOException, ClassNotFoundException {
        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(filename))) {
            Object obj = ois.readObject();
            System.out.println("對象反序列化成功!");
            return obj;
        }
    }
    
    public static void main(String[] args) {
        Person person = new Person("張三", 25, "123456");
        
        try {
            // 序列化
            serialize(person, "person.ser");
            
            // 反序列化
            Person deserializedPerson = (Person) deserialize("person.ser");
            System.out.println("反序列化后的對象: " + deserializedPerson);
            // 輸出: Person{name='張三', age=25, password='null'} (password為null因為transient)
            
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

重要概念

1. serialVersionUID

private static final long serialVersionUID = 1L;
  • 用于標(biāo)識類的版本
  • 如果類結(jié)構(gòu)發(fā)生變化,serialVersionUID 也應(yīng)改變
  • 如果不指定,JVM 會自動生成,但可能導(dǎo)致反序列化失敗

2. transient 關(guān)鍵字

private transient String password;  // 不會被序列化

標(biāo)記不需要序列化的字段,如:

  • 敏感信息(密碼)
  • 臨時數(shù)據(jù)
  • 可重新計算的數(shù)據(jù)

3. 自定義序列化

public class CustomPerson implements Serializable {
    private String name;
    private int age;
    
    // 自定義序列化方法
    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();  // 默認(rèn)序列化
        // 可以添加額外的序列化邏輯
    }
    
    // 自定義反序列化方法
    private void readObject(ObjectInputStream ois) 
            throws IOException, ClassNotFoundException {
        ois.defaultReadObject();  // 默認(rèn)反序列化
        // 可以添加額外的反序列化邏輯
    }
}

4. Externalizable 接口

import java.io.*;

public class ExternalizablePerson implements Externalizable {
    private String name;
    private int age;
    
    // 必須有無參構(gòu)造器
    public ExternalizablePerson() {}
    
    public ExternalizablePerson(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeInt(age);
    }
    
    @Override
    public void readExternal(ObjectInput in) 
            throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        age = in.readInt();
    }
}

序列化的注意事項

安全問題

// 反序列化可能存在安全風(fēng)險
Object obj = ois.readObject();  // 可能執(zhí)行惡意代碼
  • 反序列化不受信任的數(shù)據(jù)可能導(dǎo)致代碼執(zhí)行
  • 建議使用白名單驗證類
  • 考慮使用安全的序列化框架

性能問題

  • Java 原生序列化性能較差
  • 生成的字節(jié)流較大
  • 考慮使用其他序列化框架

其他序列化框架

1. JSON 序列化(Jackson)

import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();

// 序列化為 JSON
String json = mapper.writeValueAsString(person);

// 從 JSON 反序列化
Person person = mapper.readValue(json, Person.class);

2. Protocol Buffers

// 需要定義 .proto 文件
// 高性能、跨語言、體積小

3. 其他框架

  • Gson:Google 的 JSON 庫
  • Fastjson:阿里巴巴的 JSON 庫
  • Kryo:高性能二進(jìn)制序列化
  • Hessian:二進(jìn)制序列化協(xié)議

最佳實踐

  1. 始終聲明 serialVersionUID
  2. 使用 transient 保護(hù)敏感數(shù)據(jù)
  3. 考慮使用 JSON 等文本格式替代二進(jìn)制序列化
  4. 反序列化時進(jìn)行數(shù)據(jù)驗證
  5. 對于性能敏感場景,使用專業(yè)序列化框架
  6. 避免序列化不可信的數(shù)據(jù)
  7. 不要序列化包含資源(如文件句柄、數(shù)據(jù)庫連接)的對象

總結(jié)

特性Java 原生序列化JSON 序列化Protocol Buffers
可讀性二進(jìn)制文本二進(jìn)制
性能一般較慢很快
跨語言僅 Java支持支持
體積較大較大很小
使用場景Java 內(nèi)部使用Web API高性能場景

選擇合適的序列化方式取決于具體的使用場景、性能要求和跨語言需求。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

瓦房店市| 金昌市| 阿勒泰市| 宜君县| 顺昌县| 南汇区| 阿图什市| 建湖县| 无锡市| 社旗县| 阿拉善盟| 桓台县| 泗水县| 东至县| 东光县| 额济纳旗| 颍上县| 东方市| 广平县| 中超| 梅河口市| 从江县| 东海县| 任丘市| 德化县| 古田县| 安多县| 玛曲县| 乌拉特中旗| 霞浦县| 虹口区| 兴化市| 平南县| 济南市| 镇江市| 洮南市| 绥化市| 屏东市| 澄城县| 阿坝县| 巴林左旗|