对象字节流

对象输入流(ObjectInputStream)

ObjectInputStream 用于从输入源(如文件、网络等)读取字节流并反序列化为对象

ObjectInputStream必须基于 InputStream(如 FileInputStream)创建,用于从源中反序列化对象

常用方法

  1. Object readObject()

    • 作用: 从输入流中读取字节并反序列化为对象。
    • 返回值: 反序列化后的对象。
    • 注意: 反序列化时,对象的类必须存在于 JVM 中,并且必须实现 java.io.Serializable 接口
  2. int readInt()、double readDouble() 等,作用: 读取基本数据类型

  3. void close(),作用: 关闭输入流并释放资源

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    
    public class ObjectInputStreamExample {
        public static void main(String[] args) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
                Person person = (Person) ois.readObject(); // 反序列化对象
                System.out.println("从文件中读取的对象: " + person);
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    

注意事项

  • 只有实现了 java.io.Serializable 接口的类才能被序列化
  • serialVersionUID 是序列化版本号,用于标识类的版本
  • 如果类的结构发生变化(如添加或删除字段),反序列化时会检查 serialVersionUID。如果不一致,会抛出 InvalidClassException。
  • 建议显式定义 serialVersionUID
  • 使用 transient 关键字修饰的字段不会被序列化
  • 静态字段不会被序列化,静态字段属于类,而不是对象,因此不会被序列化

对象输出流(ObjectOutputStream)

ObjectOutputStream 用于将对象序列化为字节流并写入输出目标(如文件、网络等)

ObjectOutputStream必须基于 OutputStream(如 FileOutputStream)创建,用于将对象序列化到目标中

常用方法

  1. void writeObject(Object obj)
    • 作用: 将对象序列化并写入输出流。
    • 参数: obj 是要序列化的对象。
    • 注意: 对象必须实现 java.io.Serializable 接口,否则会抛出 NotSerializableException
  2. void flush()
  3. void close()
  4. void writeInt(int val)、void writeDouble(double val) 等
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

// 定义一个可序列化的类
class Person implements Serializable {
    private static final long serialVersionUID = 1L; // 序列化版本号
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

public class ObjectOutputStreamExample {
    public static void main(String[] args) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
            Person person = new Person("Alice", 25);
            oos.writeObject(person); // 序列化对象并写入文件
            System.out.println("对象已序列化并写入文件");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

一些知识点

  • 如果序列化的对象中存在对象字段,则该对象也需要实现序列化接口
// 未实现 Serializable 的类
class Dog{

}

class Person implements Serializable {
    private String name;
    private Dog dog=new Dog();//如果该字段是静态的或者transient修饰的则可以
}

//下面的情况是可以进行序列化的,因为dog的值为null,null值是可以进行序列化的
class Dog{

}
class Person implements Serializable {
    private String name;
    private static Dog dog;
}
posted @ 2025-03-17 20:58  QAQ001  阅读(24)  评论(0)    收藏  举报