Serializable接口的作用;Externalizable自定义序列化和反序列化

简介

Java类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法进行序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。
实现这个接口时通常都会自定义一个SerializableUID,那么这个SerializableUID是用来干什么的呢。

可以知道序列化是将对象的状态信息转换为可存储或传输的形式的过程。其实就是保存为字符串到磁盘里。那么当反序列化的时候其作用就来了,虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化ID是否一致,这个所谓的序列化ID,就是我们在代码中定义的serialVersionUID

简单来说就是反序列化的时候,发现serialUID不一样的时候就报错.

而且在序列化的时候如果没有定义这个序列化id,系统会默认给上一个值。

序列化和反序列化的时候自定义操作

Java中还提供了Externalizable接口,也可以实现它来提供序列化能力。

Externalizable继承自Serializable,该接口中定义了两个抽象方法:writeExternal()readExternal()

原因是在序列化过程中,如果被序列化的类中定义了writeObjectreadObject方法,虚拟机会试图调用对象类里的writeObjectreadObject方法,进行用户自定义的序列化和反序列化。

如果没有这样的方法,则默认调用是ObjectOutputStreamdefaultWriteObject方法以及ObjectInputStreamdefaultReadObject方法。

使用demo如下

package com.felix.spring_cloud_one;


import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;


public class TestVO implements Externalizable {

    private String name;

    private Integer age;

    private String address;

    public TestVO() {
    }

    public TestVO(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(name);
        out.writeUTF(address = name + age);
        out.writeInt(age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = in.readUTF();
        address = in.readUTF();
        age = in.readInt();
    }
}
@Test
public void test1(){
    TestVO vo = new TestVO("小张", 20, "nb");
    File file = new File("a.user");
    ObjectOutputStream oos = null;
    try {
        oos = new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(vo);
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        TestVO vo2 = (TestVO) ois.readObject();
        System.out.println(vo2);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}
上一篇:win7中如何解决“该项不适用于在指定状态下使用”


下一篇:面向对象编程(下)