java IO流 序列化流

java提供了一种序列化机制,一个字节序列可以表示为一个对象,相当于对象存储到文件中去了,具有持久化。反序列化,从字节序列文件里面把重构成对象。

protectedObjectOutputStream()

为完全重新实现ObjectOutputStream的子类提供一种方法,不必分配刚刚被ObjectOutputStream实现使用的私有数据。

 ObjectOutputStream(OutputStream out)

创建一个写入指定的OutputStream的ObjectOutputStream。

构造方法
ModifierConstructor and Description
protectedObjectInputStream()

为完全重新实现ObjectInputStream的子类提供一种方法,不必分配刚刚被ObjectInputStream实现使用的私有数据。

 ObjectInputStream(InputStream in)

创建从指定的InputStream读取的ObjectInputStream。

 序列化

如果是序列化集合,集合元素的对象也需要实现Serializable接口

public class Test {
    public static void main(String[] args) {
        /**
         *  java.io.ObjectOutputStream类继承OutputStream,所以该类也表示字节输出流
         *  序列化操作:
         *  void	writeObject(Object obj)
         * 将指定的对象写入ObjectOutputStream。
         *  注意:
         *  被序列化的对象必须实现Serializable接口
         */
        Student zhangsan = new Student("张三", 18);
        try (
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("IO流\\aaa\\zhangsan.txt"));
        ){
            objectOutputStream.writeObject(zhangsan);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

反序列化

注意事项:

1,对于jvm可以反序列化对象,它是必须要能找到class文件的类(在项目下的out目录下面)

2,能找到class文件的类,但是class文件在序列化对象后发生了修改,那么也会报异常。

我们在序列化的时候,会自动生成一个序列化id。如何解决呢?在属性中加上static final long serialVersionUID = 42L;

这样如果对象文件改了,还是会用原来的对象反序列化。

public class Test2 {
    /**
     * 反序列化
     * Object	readObject()
     * 从ObjectInputStream读取一个对象。
     */
    public static void main(String[] args) {
        try (
                ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("IO流\\aaa\\zhangsan.txt"));
        ){
            Student zhangsan = (Student)objectInputStream.readObject();
            System.out.println(zhangsan.getName());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

如果一个对象的属性不想被序列化,那么就使用transient关键字标明为瞬态。如下,这个时候我们反序列化后,获取age属性,发现值是默认值null

public class Student implements Serializable {
    private String name;
    private transient Integer age;
    public Student() { }
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) && Objects.equals(age, student.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

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

posted @ 2022-07-04 23:43  在线电影制作人  阅读(4)  评论(0)    收藏  举报  来源