参考答案:
在 Java 中,序列化是将对象的状态转换为字节流,以便将其存储到文件、数据库或通过网络传输。反序列化是将字节流还原为对象的过程。Java 提供了一种机制来实现对象的序列化,主要通过实现 java.io.Serializable
接口来实现。
Serializable
接口要使一个 Java 对象可序列化,必须使它的类实现 java.io.Serializable
接口。这个接口是一个标记接口,意味着它没有任何方法,只有通过标记一个类为可序列化,JVM 才会知道该类的对象可以被序列化。
1import java.io.Serializable; 2 3public class Person implements Serializable { 4 private String name; 5 private int age; 6 7 public Person(String name, int age) { 8 this.name = name; 9 this.age = age; 10 } 11 12 public String getName() { 13 return name; 14 } 15 16 public int getAge() { 17 return age; 18 } 19}
ObjectOutputStream
序列化对象ObjectOutputStream
是一个用于将对象写入输出流的类,它提供了 writeObject()
方法来序列化对象。
1import java.io.*; 2 3public class SerializationExample { 4 public static void main(String[] args) { 5 // 创建对象 6 Person person = new Person("John Doe", 30); 7 8 try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) { 9 // 序列化对象到文件 10 oos.writeObject(person); 11 System.out.println("对象已成功序列化!"); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } 15 } 16}
在这个示例中,Person
对象被序列化并保存到名为 person.ser
的文件中。
ObjectInputStream
反序列化对象ObjectInputStream
是一个用于从输入流中读取对象的类,它提供了 readObject()
方法来反序列化对象。需要注意的是,反序列化时,类必须存在,否则会抛出 ClassNotFoundException
。
1import java.io.*; 2 3public class DeserializationExample { 4 public static void main(String[] args) { 5 try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) { 6 // 反序列化对象 7 Person person = (Person) ois.readObject(); 8 System.out.println("反序列化对象: " + person.getName() + ", " + person.getAge()); 9 } catch (IOException | ClassNotFoundException e) { 10 e.printStackTrace(); 11 } 12 } 13}
serialVersionUID
在 Java 序列化过程中,每个可序列化的类都会生成一个 serialVersionUID
,用于确保类的版本一致性。serialVersionUID
是一个版本号,确保序列化与反序列化时版本的兼容性。
serialVersionUID
不匹配),则会抛出 InvalidClassException
。你可以手动声明 serialVersionUID
,以确保版本的兼容性。
1import java.io.Serializable; 2 3public class Person implements Serializable { 4 private static final long serialVersionUID = 1L; // 手动声明 serialVersionUID 5 6 private String name; 7 private int age; 8 9 // 构造方法、getter 和 setter 10}
transient
关键字有时候,你不希望某些属性参与序列化过程。可以使用 transient
关键字来标记不需要序列化的字段。这些字段在序列化和反序列化时会被忽略。
1import java.io.*; 2 3public class Person implements Serializable { 4 private String name; 5 private int age; 6 private transient String password; // 不会被序列化 7 8 public Person(String name, int age, String password) { 9 this.name = name; 10 this.age = age; 11 this.password = password; 12 } 13 14 // getter 和 setter 15}
在上面的例子中,password
字段会被忽略,不会序列化到文件中。
readObject()
和 writeObject()
方法你可以通过重写 writeObject()
和 readObject()
方法来控制自定义的序列化和反序列化过程。这在需要进行特定处理时非常有用。
writeObject(ObjectOutputStream out)
:可以在序列化对象时进行自定义处理。readObject(ObjectInputStream in)
:可以在反序列化对象时进行自定义处理。1import java.io.*; 2 3public class Person implements Serializable { 4 private String name; 5 private int age; 6 7 public Person(String name, int age) { 8 this.name = name; 9 this.age = age; 10 } 11 12 // 自定义序列化方法 13 private void writeObject(ObjectOutputStream out) throws IOException { 14 out.defaultWriteObject(); // 默认的序列化 15 // 可以在这里进行额外的序列化操作 16 System.out.println("对象序列化中..."); 17 } 18 19 // 自定义反序列化方法 20 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 21 in.defaultReadObject(); // 默认的反序列化 22 // 可以在这里进行额外的反序列化操作 23 System.out.println("对象反序列化中..."); 24 } 25}
readObject()
方法或其他方法进行处理。Serializable
接口,否则会抛出 NotSerializableException
。serialVersionUID
来确保反序列化时版本兼容。最近更新时间:2024-12-24