java:使用对象流完成集合的序列化和反序列化 2021

java:使用对象流完成集合的序列化和反序列化

java中提供了一种对象序列化的机制,可以将对象和字节序列之间进行转换

  • 序列化 程序中,可以用一个字节序列来表示一个对象,该字节序列包含了对象的类型、对象中的数据等。
    如果这个字节序列写出到文件中,就相当于在文件中持久保存了这个对象的信息
  • 反序列化 相反的过程,从文件中将这个字节序列读取回来,在内存中重新生成这个对象,对象的类型、对象中的数据等,都和之前的那个对象保持一致。(注意,这时候的对象和之前的对象,内存地址可能是不同的)

对象流

ObjectInputStream 和 ObjectOutputStream

java.io.ObjectOutputStream:将Java对象转换为字节序列,并输出到内存、文件、网络等地方

注意,具体输出到什么地方,要看 ObjectOutputStream “包裹”的是哪一个节点流

java.io.ObjectInputStream:从某一个地方读取出对象的字节序列,并生成对应的对象。

在java中,并非所有对象都可以进行序列化和反序列化,而是只有实现了指定接口的对象才可以进行。
java.io.Serializable 接口

Serializable 接口给需要序列化的类,提供了一个序列版本号:
serialVersionUID
该版本号的目的,是用于验证序列化的对象和对应类是否版本匹配

默认情况下,每次修改代码编译生成的新的class文件中,都会根据当前类的信息计算出一个序列化版本号,之前序列化的字节中的保存的是之前老的版本号,和现在这个新的不一致,然后就会报错

举例:

序列化


import java.io.Serializable;

/*
* 要想对象实现序列化 需要满足以下要求
*
* 1、需要实现接口 Serializeble
* 2、添加序列化版本号 提供一个全局变量 serialVersionUID
* 3、除了当前Person类需要实现Serializable接口之外,还必须保证其内部所属性
*   也必须是可序列化的。(默认情况下,基本数据类型可序列化)
*
* 补充:ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
*
* */

public class Person implements Serializable{

    public static final long SerialVersionUID=4723343L;
    private String name;
    private int 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;
    }

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

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

    public Person() {
    }


}


序列化代码实现:
@Test
public void testObjectOutputStream(){
    ObjectOutputStream oos = null;

    try {
        //1.
        oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
        //2.
        oos.writeObject(new String("我爱北京天安门"));
        oos.flush();//刷新操作

         oos.writeObject(new Person("陈奕迅",23));
        oos.flush();

        oos.writeObject(new Person("周杰伦",23,1001,new Account(5000)));
        oos.flush();

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(oos != null){
            //3.
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

}

反序列化:

@Test
public void testObjectInputStream(){
    ObjectInputStream ois = null;
    try {
        ois = new ObjectInputStream(new FileInputStream("object.dat"));

        Object obj = ois.readObject();
        String str = (String) obj;

        Person p = (Person) ois.readObject();
        Person p1 = (Person) ois.readObject();

        System.out.println(str);
        System.out.println(p);
        System.out.println(p1);

    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        if(ois != null){
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }



}

重新写了个例子,之前写的例子不太标准。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值