原因
网络上查到的太散,用时麻烦。验证下记一下
- Serializable接口必须实现;序列化版本号最好指定一个;这是最基础的
private static final long serialVersionUID = 2659082826995480601L;
后面的点生效优先级递增
- transient关键字,不被序列化
- JVM隐式约定三个方法用于调整序列化和反序列化
生效强于transient,即即使transient修饰了,也可以自定义将其写入。
直接操作流写入Object时,object内的transient关键字不会生效
执行顺序为:
writeReplace 将序列化对象替换为此方法返回的Object
writeObject 序列化写入后,追加执行一段逻辑,可以追加写入
readObject 反序列化读取后,追加执行一段读取逻辑,对称
private void writeObject(ObjectOutputStream out) throws IOException {
System.err.println("writeObject");
}
private void readObject(ObjectInputStream ins) throws IOException, ClassNotFoundException {
System.err.println("readObject");
}
private Object writeReplace(){
System.err.println("writeReplace");
return new TestBean();
}
- 可以完全自定义序列化逻辑,此时2中的约定方法将不会生效
implements Externalizable
此时2中JVM约定方法不会生效
直接操作流写入Object时,object内的transient关键字不会生效
测试类
package support;
import java.io.*;
/**
* @author zhengxy.
* @date 2024/11/11 9:50
*/
public class SerializeTest {
public static class TestBean
// implements Serializable
implements Externalizable {
@Override
public String toString() {
return "age:" + age + "," + "name:" + name;
}
private int age = 123;
private transient String name = "china!";
private void writeObject(ObjectOutputStream out) throws IOException {
System.err.println("writeObject");
//将名字反转写入二进制流
this.name = name + "america?";
this.age = 9981;
out.writeObject(new StringBuffer(this.name));
out.writeInt(this.age);
}
private void readObject(ObjectInputStream ins) throws IOException, ClassNotFoundException {
System.err.println("readObject");
//将读出的字符串反转恢复回来
this.name = ((StringBuffer) ins.readObject()).toString();
this.age = ins.readInt();
}
private Object writeReplace() {
System.err.println("writeReplace");
return new TestBean();
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
System.err.println("writeExternal");
out.writeObject(this);
// out.writeObject(new StringBuffer(this.name));
// out.writeInt(this.age);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
System.err.println("readExternal");
TestBean o = (TestBean) in.readObject();
this.name = o.name;
this.age = o.age;
// this.name = ((StringBuffer) in.readObject()).toString();
// this.age = in.readInt();
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
TestBean bean1 = new TestBean();
File file = new File("bean1.serialize");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(bean1);
ObjectInputStream inStream = new ObjectInputStream(new FileInputStream("bean1.serialize"));
TestBean readObject = (TestBean) inStream.readObject();
System.out.println("反序列化后:" + readObject.toString());
}
}