《网络安全学习者必看!Java序列化与反序列化深度解读》

序列化与反序列化的代码讲解

基本实现

这里我们可以先跑一跑代码,看一看。

Run SerializationTest.java

Run UnserializationTest.java

前文我们说,序列化与反序列化的根本目的是数据的传输。

  • SerializationTest.java

咱们来想象一个有趣的小实验:把Java对象变成魔法饼干存进罐子里!

你心爱的玩具需要保存起来,方便下次继续玩

  1. 【准备魔法罐子】首先咱们要找一个透明的密封罐(FileOutputStream),用来装我们的魔法饼干
    FileOutputStream就像个透明玻璃罐,用来存放最终的成果:"ser.bin"就是我们的魔法饼干罐
  2. 【施展序列化魔法】然后拿出神奇裱花袋(ObjectOutputStream),把裱花嘴套在罐口上
    ObjectOutputStream就像能把对象变成数据流的神奇工具,接在罐子上准备输出
  3. 【注入对象精华】最后像挤奶油一样,把Java对象"滋溜"一下挤进罐子!
    oos.writeObject(obj) 这一瞬间,你的对象就被转化成魔法数据,永久保存在二进制文件里啦~

下次想找回玩具时,用ObjectInputStream这个反向魔法,就能把饼干变回原来的玩具对象啦!就像这样:

java 复制代码
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.bin"));  
Object recoveredToy = ois.readObject();

Serializable 接口

(1) 序列化类的属性没有实现 Serializable 那么在序列化就会报错

想象你要参加「对象王国」的狂欢派对,入场券就是这个Serializable接口!🎫

▶️ 特点:

  1. 空白的魔法契约

    public class MagicCookie implements Serializable { ... }

    • 只需在类头顶上贴上这个标签(implements Serializable
    • 不用写任何魔法咒语(不需要实现任何方法)
    • 就像拿到一张「免笔试入场券」
  2. 自动触发魔法阵

    java 复制代码
    oos.writeObject(cookie); // ✨ 自动施放序列化咒语
    • Java会悄悄检查你的「入场券」
    • 如果没贴标签?→ 抛出InvalidClassException(就像被保安拦在派对门外!)
java 复制代码
public class Person implements Serializable { // 🎯 正确佩戴许可证!
    private String name;
    private int age;
}

当删除implements Serializable时:

java 复制代码
public class Person { // 😱 许可证被偷了!
    private String name;
    private int age;
}

👉 ​后果:运行时会弹出超恐怖的红色警告!

Exception in thread "main" java.io.NotSerializableException: src.Person

就像你试图带着普通书包穿越时空隧道,被守卫机器人用激光枪拦截!

终极比喻记忆法 🧩

  • Serializable → 免费基础会员卡(躺平就能用)
  • Externalizable → VIP定制服务(需要自己动手配置)
  • 未实现接口 → 想带宠物进电影院却没买宠物票(一定会被拦下!)
  • JVM → 严格的时空管理局警察(检查你的证件!)

此外,如果我们此处将 Serializable 接口删除掉的话,会导致如下结果。

(2) 在反序列化过程中,它的父类如果没有实现序列化接口,那么将需要提供无参构造函数来重新创建对象。
(3)一个实现 Serializable 接口的子类也是可以被序列化的。
(4) 静态成员变量是不能被序列化

序列化是针对对象属性的,而静态成员变量是属于类的。

(5) transient 标识的对象成员变量不参与序列化")(5) transient 标识的对象成员变量不参与序列化

这里我们可以动手实操一下,想这么一个问题

  • 如何让Java对象的敏感信息"瞬间消失"?

🎯 ​任务背景

你是一名Java特工,需要护送Person对象穿越「序列化隧道」到另一个系统。但有个致命问题

⚠️ ​**name是绝密信息,绝对不能泄露!​**

怎么办?快用transient隐身喷雾!

🕶️ ​STEP 1:装备隐身喷雾(修改Person类)​

打开Person.java,找到第7行秘密武器库:

java 复制代码
// 原版(危险!名字会被记录)
private String name;

// 特工改造版 → 喷上transient隐身喷雾!
private transient String name;  // 🕶️ 隐身模式启动

💻 ​STEP 2:执行加密传输(序列化测试)​

运行SerializationTest.java,观察特工日志:

java 复制代码
// 序列化前的对象状态
Person{name='aa', age=22} 

// 穿越序列化隧道后...
System.out.println("序列化文件内容:");
// 用hex编辑器查看ser.bin → name字段已消失!🚀

🔓 ​STEP 3:接收端解密验证(反序列化测试)​

运行UnserializeTest.java,发现惊人变化:

java 复制代码
// 反序列化后的对象
Person{name='null', age=22} 
// ❗ name变成null,但age完好无损!

🚀 ​完整特工代码(SerializationTest.java

java 复制代码
package com.tingjun;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializationTest {

    public static void serialize(Object obj) throws IOException {
        // 🕶️ 创建序列化隧道入口
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
        oos.close(); // 重要!关闭资源
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 🎯 特工代号设置
        Person person = new Person("aa", 22);
        System.out.println("【特工出发前状态】");
        System.out.println(person); // Person{name='aa', age=22}

        // 🚀 启动序列化传送
        serialize(person);

        // 🔍 接收端反序列化检测
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.bin"));
        Person deserializedPerson = (Person) ois.readObject();
        ois.close();

        System.out.println("\n【穿越序列化隧道后】");
        System.out.println("序列化文件内容:"); // ✨ 关键输出位置!
        System.out.println(deserializedPerson); // Person{name='null', age=22}
    }
}

上述说的还是关于序列化本身的一些特性,明天我们接着讲一讲序列化的安全问题是如何产生的。

相关推荐
亚力山大抵16 分钟前
实验六-使用PyMySQL数据存储的Flask登录系统-实验七-集成Flask-SocketIO的实时通信系统
后端·python·flask
做题不NG26 分钟前
大模型应用开发-LangChain4j
java
超级小忍27 分钟前
Spring Boot 中常用的工具类库及其使用示例(完整版)
spring boot·后端
今天背单词了吗98029 分钟前
算法学习笔记:7.Dijkstra 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·数据结构·笔记·算法
上海锝秉工控1 小时前
防爆拉线位移传感器:工业安全的“隐形守护者”
大数据·人工智能·安全
CHENWENFEIc1 小时前
SpringBoot论坛系统安全测试实战报告
spring boot·后端·程序人生·spring·系统安全·安全测试
高兴达1 小时前
RPC--Netty客户端实现
java·spring·rpc
重庆小透明2 小时前
力扣刷题记录【1】146.LRU缓存
java·后端·学习·算法·leetcode·缓存
lang201509282 小时前
Reactor操作符的共享与复用
java
TTc_2 小时前
@Transactional事务注解的批量回滚机制
java·事务