Java对象操作流:序列化与反序列化

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java对象操作流:序列化与反序列化相关的知识,希望对你有一定的参考价值。

文章目录

对象操作流

1. 对象序列化流

1.1.1 对象序列化介绍

  • 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象的机制。
  • 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息。
  • 字节序列写到文件(或网络)之后,相当于文件中持久保存了一个对象的信息;反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。

1.1.2 对象序列化流: ObjectOutputStream

将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象

构造方法:

方法名说明
ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法:

方法名说明
void writeObject(Object obj)将指定的对象写入ObjectOutputStream

1.1.3 序列化示例代码

注意事项:一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口(Serializable是一个标记接口,实现该接口,不需要重写任何方法 )

学生类:

public class Student implements Serializable 
    private String name;
    private int age;

    public Student() 
    

    public Student(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;
    

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

测试类

class ObjectOutputStreamDemo 
    public static void main(String[] args) throws IOException 
        //ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("StreamFile\\\\oos.txt"));

        //创建对象
        Student s = new Student("赵丽颖", 18);

        //void writeObject(Object obj):将指定的对象写入ObjectOutputStream
        oos.writeObject(s);

        //释放资源
        oos.close();
    

2. 对象反序列化流

2.1 对象反序列化流: ObjectInputStream

  • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象

构造方法

方法名说明
ObjectInputStream(InputStream in)创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法

方法名说明
Object readObject()从ObjectInputStream读取一个对象

2.2 示例代码

class ObjectInputStreamDemo 
    public static void main(String[] args) throws IOException, ClassNotFoundException 
        //ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("StreamFile\\\\oos.txt"));

        //Object readObject():从ObjectInputStream读取一个对象
        Object obj = ois.readObject();

        Student s = (Student) obj;
        System.out.println(s.getName() + "," + s.getAge());

        ois.close();
    

3. serialVersionUID&transient

3.0 遇到的问题

用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

首先进行序列化操作
再将Bean对象中的private改为public反序列化

会出问题,会抛出InvalidClassException异常

原因分析

仔细阅读错误,他说之前的serialVersionUID与现在的不匹配了

这是因为Java虚拟机会判断如果我们自己没有定义,那么虚拟机会根据类中的信息会自动的计算出一个序列号。当你修改了Bean类的时候,新的类的序列号就会重新计算获得。

关键原因:如果我们修改了类中的信息.那么虚拟机会再次计算出一个序列号。

3.1 serialVersionUID

那我么如何解决上面的问题呢?

那就是不让虚拟机帮我们自动计算,我们自己手动给出.而且这个值不要变.

首先我们要重新序列化,给对象所属的类加一个serialVersionUID

 private static final long serialVersionUID = 42L;


运行没毛病

3.2 transient

还要一个问题,如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?

给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
如下所示:

4. 示例代码

学生类


测试类

public static void main(String[] args) throws IOException, ClassNotFoundException 
    Student s1 = new Student("杜子腾",16);
    Student s2 = new Student("张三",23);
    Student s3 = new Student("李四",24);
	// 序列化
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
    oos.writeObject(s1);
    oos.writeObject(s2);
    oos.writeObject(s3);
    oos.close();
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
    Object obj;
  /*  while((obj = ois.readObject()) != null)
        System.out.println(obj);
    */
   // 反序列化
   while(true)
       try 
           Object o = ois.readObject();
           System.out.println(o);
        catch (EOFException e) 
           break;
       
   
    ois.close();


文件中

以上是关于Java对象操作流:序列化与反序列化的主要内容,如果未能解决你的问题,请参考以下文章

Java核心类库-IO-对象流(实现序列化与反序列化)

java序列化与反序列化流的操作,打印流的输出

java对象序列化与反序列化

Java基础-IO流对象之序列化与反序列化

Java基础IO流序列化与反序列化

十序列化与反序列化(对象流)