1、创建可序列化的类:
package com.serializable;
import java.io.Serializable;
//序列化是指将Java对象转换为字节流的过程,而反序列化则是将字节流转换回Java对象的过程。
//通过实现Serializable接口实现序列化。
//该接口没有任何方法,只是作为一个标记接口,告诉编译器这个类可以被序列化。
//要进行序列化,需要使用ObjectOutputStream类。
//该类提供了writeObject方法,可以将对象写入到输出流中。
//序列化后的字节流可以保存到文件、数据库或网络传输等。
//实现Serializable接口的Person类
class Person implements Serializable {
private static final long serialVersionUID = 1L;
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
2、序列化该类:
package com.serializable;
import java.io.*;
//序列化是将对象转化为字节流的过程,可以将对象保存在文件中或者通过网络进行传输。
//实现序列化,首先要确保类实现Serializable接口。
//这个接口是一个标记接口,没有定义任何方法。
//只有实现了Serializable接口的类的对象才能被序列化。
//在将对象序列化之前,需要创建一个输出流,将序列化的数据写入到流中。
//可以使用ObjectOutputStream类来实现。
public class SerializationDemo {
public static void main(String[] args) {
// 创建一个Person对象
Person person = new Person("Alice", 25);
// 将对象序列化保存到文件中
try {
FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(person);
out.close();
fileOut.close();
System.out.println("Serialized data is saved in person.ser");
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、反序列化:
package com.serializable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
//要进行反序列化,需要使用ObjectInputStream类。
//该类提供了readObject方法,用于从输入流中读取对象。
//从文件"person.ser"中读取并反序列化一个Person对象。
//打印出Person对象的name和age属性,验证反序列化是否成功。
//序列化提供一种方便的方法来将对象转化为字节流以便保存或传输。
//以下几种特殊的情况,可能无法正确地序列化或者会导致意外结果:
//1. 不可序列化的字段:如果一个类中包含不可序列化的字段(比如非序列化的对象、静态变量或transient修饰的字段),
//在序列化过程中,这些字段的值将被忽略或者会导致异常。
//2. 包含其他类的匿名内部类或局部类:匿名内部类或局部类中隐式地引用了外部类的实例,而且这个外部类没有实现Serializable接口,
//那么匿名内部类或局部类也不可序列化。如果这些内部类是静态的,则可以被序列化,因为静态成员不依赖于外部类的实例。
//3. 类的结构发生变化:如果在序列化和反序列化之间对类进行了修改,比如添加或删除字段或方法,可能会导致反序列化过程失败或导致对象数据不完整。
//4. 使用自定义的序列化形式:如果在类中自定义了writeObject()或readObject()方法,用于控制对象的序列化和反序列化过程,
//并且这些方法没有正确地处理对象的字段,可能会导致意外结果。
//5. 使用不同版本的类:在对象进行反序列化时,如果使用的是与序列化时不同版本的类,可能会导致版本不匹配的问题,从而导致反序列化失败或数据不一致。
//为了正确地实施序列化和反序列化操作,在编写类时,应该遵循一些最佳实践,如确保类实现Serializable接口、处理不可序列化字段、使用合适的数据类型等。
//另外也可以使用Externalizable接口来自定义类的序列化和反序列化过程,以更好地控制对象的存储形式。
public class DeserializationDemo {
public static void main(String[] args) {
Person person = null;
// 从文件中反序列化对象
try {
FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
person = (Person) in.readObject();
in.close();
fileIn.close();
} catch (IOException e) {
e.printStackTrace();
return;
} catch (ClassNotFoundException e) {
System.out.println("Person class not found");
e.printStackTrace();
return;
}
System.out.println("Deserialized data:");
System.out.println("Name: " + person.name);
System.out.println("Age: " + person.age);
}
}
运行结果如下: