本文共 4098 字,大约阅读时间需要 13 分钟。
在Java编程中,ObjectInputStream和ObjectOutputStream是处理对象序列化和反序列化的核心类。ObjectOutputStream用于将对象转化为流数据,以便在文本文件中存储或通过网络传输。而ObjectInputStream则用于将流数据还原为对象。这两者在数据传输和持久化存储中发挥着重要作用。
使用ObjectOutputStream进行对象序列化时,首先需要确保目标类实现了Serializable接口。该接口是一个标记接口,类通过实现它可以启用其序列化功能。如果未实现该接口的类将无法进行序列化或反序列化操作,会抛出NotSerializableException异常。
以下是实现Serializable接口的示例代码:
public class Person implements Serializable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }} 如果类Person未实现Serializable接口,尝试将其序列化就会抛出以下错误信息:
Exception in thread "main" java.io.NotSerializableException: com.ginger.demo01.Person at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1185) at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:349) at com.ginger.demo01.ObjectInputStreamDemo.writer(ObjectInputStreamDemo.java:24) at com.ginger.demo01.ObjectInputStreamDemo.main(ObjectInputStreamDemo.java:8)
在反序列化过程中,如果类没有指定序列化版本号(serialVersionUID),可能会出现InvalidClassException。以下是一个常见的解决方案:
public class Person implements Serializable { private static final long serialVersionUID = 6499259360078010285L; private String name; private int age; // 其他代码保持不变} transient关键字来控制哪些字段参与序列化:public class Person implements Serializable { private static final long serialVersionUID = 6499259360078010285L; private String name; private transient String chinese; // 使用transient关键字使chinese字段不参与序列化 // 其他代码保持不变} 以下是一个完整的代码示例,展示了如何使用ObjectInputStream和ObjectOutputStream进行数据的读写操作:
public class ObjectInputStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { writer(); } private static void writer() throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt")); Person p = new Person("格雷福斯", 40); oos.writeObject(p); oos.close(); }} public class ObjectInputStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { reader(); } private static void reader() throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt")); Object p = ois.readObject(); System.out.println(p); ois.close(); }} 以下是一个实现了Serializable接口的实体类:
public class Person implements Serializable { private static final long serialVersionUID = 6499259360078010285L; private String name; private int age; private transient String chinese; public Person(String name, int age, String chinese) { this.name = name; this.age = age; this.chinese = chinese; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", chinese='" + chinese + '\'' + '}'; }} 在实际应用中,如果没有指定serialVersionUID,可能会出现以下错误:
InvalidClassException: com.ginger.demo01.Person; local class incompatible: stream classdesc serialVersionUID = 311183030272692197, local class serialVersionUID = 6499259360078010285
transient关键字来控制哪些字段参与序列化。通过以上方法,开发者可以实现对象的序列化和反序列化操作。在实际开发中,建议在类定义时手动指定serialVersionUID,并合理使用transient关键字,以确保序列化过程的稳定性和兼容性。
转载地址:http://hlya.baihongyu.com/