0x01
开始学习JAVA反序列化,参考 《安全漫谈》和feng师傅的文章一步一步来,希望 能赶在这个学期学完java最基础的东西, 笔记做到这里方便自己查阅,也是事先实操了一下 ,才写的笔记
概念:
JAVA 序列化 就是把一个 JAVA Object 变成一个二进制字节数组 即 byte[]
JAVA 反序列化 就是把一个 二进制数组 byte[] 变回Java 对象 ,即JAva Object
序列化/反序列化具备条件
如果一个类 实现序列化或反序列化操作, 必须要实现 Serializable
接口或者Externalizable
接口。 最好还要有一个 serialVersionUID 属性
这属性的介绍:
每个可序列化的类在序列化时都会关联一个版本号 , 这个版本号就是 serialVersionUID 属性 .
在反序列化过程中会根据这个版本号来判断序列化对象的发送者和接收着是否有与该序列化/反序列化过程兼容的类 .( 简单的说就是序列化过程和反序列化过程都需要被序列化的类 , 通过 serialVersionUID 属性来判断这两个类的版本是否相同 , 是否是同一个类 ) . 如果不相同 , 则会抛出 InvalidClassException 异常
serialVersionUID 属性必须通过 static final long 修饰符来修饰 .
如果可序列化的类未声明 serialVersionUID 属性 , 则 Java 序列化时会根据类的各种信息来计算默认的 serialVersionUID 值 . 但是 Oracle 官方文档强烈建议所有可序列化的类都显示声明 serialVersionUID 值 .
Serializable
只是一个空接口,没有任何操作
只是一个标识接口,意味着实现了这个接口的类 可以进行序列化和反序列化操作。
Externalizable
继承的 Serializable
接口的接口
Externalizable 接口使用较为麻烦,一般会使用Serializable
ObjectOutputStream
官方文档:
关键是 writeObject 方法 ,可以将对象写入数据流中(序列化)
需要注意的是
对象的默认序列化机制会写入对象的类,类签名以及所有非瞬态和非静态字段的值。 对其他对象的引用(瞬态或静态字段除外)也会导致这些对象被写入。
需要注意的是,static 字段是不会被序列化的,只会保留原有的值(个人理解
关于类签名:
在开发 JNI( Java Native Interface , Java 本地接口 ) 时需要调用