0x01 前言
在Java中实现对象反序列化非常简单
只需要继承并实现 java.io.Serializable 或是 java.io.Externalizable 接口即可被序列化
其中 java.io.Externalizable 只是实现了 java.io.Serializable 的接口
但是两者还是有区别的,区别如下:
注意: 复制了P牛的小圈子一个大佬发的结论,比我自己总结的更好, 总的来说,有点小小修改
- 实现
Externalizable, 序列化过程需要开发人员自己实现。未实现writeExternal()和readExternal(),则序列化时不会保存和读取任何字段。属性使用和不使用 transient 修饰,无任何区别 Externalizable优先级比Serializable更高- 如果在序列化的时候使用了构造方法的情况下,那
Externalizable必须要创建默认的无参构造方法,Serializable方法可以没有默认的无参构造方法
其中第三点,需要在在在注意一下,使用 Externalizable 的时候:
如果你在序列化的时候没有使用构造方法!!!!!
那么是可以不创建无参构造方法也能成功反序列化的
但是如果你使用了构造方法来进行序列化!!!!!
那么则必须创建一个无参构造方法,这样才能成功的反序列化
0x02 类方法讲解
Externalizable 类主要有两个方法writeExternal() # 类被序列化时调用readExternal() # 类被反序列化时调用
0x03 例子
0x03.1 无构造方法例子
0x03.1.1 writeExternal()
// 第一步创建 ExternalizableTest1 类package java反序列化测试;import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;public class ExternalizableTest1 implements Externalizable {public String test1;public transient String test2;@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject("1111");out.writeObject("2222");System.out.println("writeExternal.......");}@Overridepublic void readExternal(ObjectInput in) {}}
// 第二步-序列化 ExternalizableTest1 类package java反序列化测试;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;public class SerializeDemo4 {public static void main(String[] args) {// ExternalizableTest1 序列化ExternalizableTest1 e = new ExternalizableTest1();try {FileOutputStream fileOut = new FileOutputStream("./src/main/java/java反序列化测试/ExternalizableTest1.ser");ObjectOutputStream out = new ObjectOutputStream(fileOut);out.writeObject(e);out.close();fileOut.close();} catch (IOException i) {i.printStackTrace();}}}// 运行结果:// 输出: writeExternal.......// 并且会在在 /src/main/java/java反序列化测试/ 生成一个 ExternalizableTest1.ser 文件
0x03.1.2 readExternal()
// 第一步创建 ExternalizableTest2 类package java反序列化测试;import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;public class ExternalizableTest2 implements Externalizable {public String test1;public transient String test2;@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject("1111");out.writeObject("2222");System.out.println("writeExternal.......");}@Overridepublic void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {this.test1 = (String) in.readObject();this.test2 = (String) in.readObject();System.out.println("readExternal.......");}}
// 第二步-序列化 ExternalizableTest2 类package java反序列化测试;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;public class SerializeDemo5 {public static void main(String[] args) {// ExternalizableTest2 序列化ExternalizableTest2 e = new ExternalizableTest2();try {FileOutputStream fileOut = new FileOutputStream("./src/main/java/java反序列化测试/ExternalizableTest2.ser");ObjectOutputStream out = new ObjectOutputStream(fileOut);out.writeObject(e);out.close();fileOut.close();} catch (IOException i) {i.printStackTrace();}}}// 运行结果:// 输出: writeExternal.......// 并且会在在 /src/main/java/java反序列化测试/ 生成一个 ExternalizableTest2.ser 文件
// 第三步-反序列化 ExternalizableTest2 类package java反序列化测试;import java.io.FileInputStream;import java.io.IOException;import java.io.ObjectInputStream;public class DeserializationDemo5 {public static void main(String[] args) {// 反序列化 ExternalizableTest2try {FileInputStream fileIn = new FileInputStream("./src/main/java/java反序列化测试/ExternalizableTest2.ser");ObjectInputStream in = new ObjectInputStream(fileIn);ExternalizableTest2 e = (ExternalizableTest2) in.readObject();in.close();fileIn.close();System.out.println(e.test1);System.out.println(e.test2);} catch (IOException i) {i.printStackTrace();return;} catch (ClassNotFoundException c) {System.out.println("ExternalizableTest2 class not found");c.printStackTrace();return;}}}// 运行结果:// 输出:// readExternal() 被调用输出 readExternal.......// e.test1 被打印输出 1111// e.test2 被打印输出 2222
0x03.2 有构造方法例子
0x03.2.1 writeExternal()
// 第一步创建 ExternalizableTest3 类package java反序列化测试;import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;public class ExternalizableTest3 implements Externalizable {public String test1;public transient String test2;public ExternalizableTest3() {}public ExternalizableTest3(String test1, String test2) {super();this.test1 = test1;this.test2 = test2;}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(this.test1);out.writeObject(this.test2);System.out.println("writeExternal.......");}@Overridepublic void readExternal(ObjectInput in) {}}
// 第二步-序列化 ExternalizableTest3 类package java反序列化测试;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;public class SerializeDemo6 {public static void main(String[] args) {// ExternalizableTest3 序列化ExternalizableTest3 e = new ExternalizableTest3("test11", "test22");try {FileOutputStream fileOut = new FileOutputStream("./src/main/java/java反序列化测试/ExternalizableTest3.ser");ObjectOutputStream out = new ObjectOutputStream(fileOut);out.writeObject(e);out.close();fileOut.close();} catch (IOException i) {i.printStackTrace();}}}// 运行结果:// 输出: writeExternal.......// 并且会在在 /src/main/java/java反序列化测试/ 生成一个 ExternalizableTest3.ser 文件
0x03.2.2 readExternal()
// 第一步创建 ExternalizableTest4 类package java反序列化测试;import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;public class ExternalizableTest4 implements Externalizable {public String test1;public transient String test2;public ExternalizableTest4() {}public ExternalizableTest4(String test1, String test2) {super();this.test1 = test1;this.test2 = test2;}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(this.test1);out.writeObject(this.test2);System.out.println("writeExternal.......");}@Overridepublic void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {this.test1 = (String) in.readObject();this.test2 = (String) in.readObject();System.out.println("readExternal.......");}}
// 第二步-序列化 ExternalizableTest4 类package java反序列化测试;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;public class SerializeDemo7 {public static void main(String[] args) {// ExternalizableTest4 序列化ExternalizableTest4 e = new ExternalizableTest4("test11", "test22");try {FileOutputStream fileOut = new FileOutputStream("./src/main/java/java反序列化测试/ExternalizableTest4.ser");ObjectOutputStream out = new ObjectOutputStream(fileOut);out.writeObject(e);out.close();fileOut.close();} catch (IOException i) {i.printStackTrace();}}}// 运行结果:// 输出: writeExternal.......// 并且会在在 /src/main/java/java反序列化测试/ 生成一个 ExternalizableTest4.ser 文件
// 第三步-反序列化 ExternalizableTest4 类package java反序列化测试;import java.io.FileInputStream;import java.io.IOException;import java.io.ObjectInputStream;public class DeserializationDemo6 {public static void main(String[] args) {// 反序列化 ExternalizableTest4try {FileInputStream fileIn = new FileInputStream("./src/main/java/java反序列化测试/ExternalizableTest4.ser");ObjectInputStream in = new ObjectInputStream(fileIn);ExternalizableTest4 e = (ExternalizableTest4) in.readObject();in.close();fileIn.close();System.out.println(e.test1);System.out.println(e.test2);} catch (IOException i) {i.printStackTrace();return;} catch (ClassNotFoundException c) {System.out.println("ExternalizableTest4 class not found");c.printStackTrace();return;}}}// 运行结果:// 输出:// readExternal() 被调用输出 readExternal.......// e.test1 被打印输出 test11// e.test2 被打印输出 test22
