java基础之序列化

1.什么是序列化?

简单点来说就是对对象的状态进行保存,注意是对象的状态而不是方法并且只能保存对象的普通成员变量而不能保存对象的静态变量。

2.怎么实现序列化?

实现序列化一般是通过实现Serializable接口或者Serializable的子接口Externalizable。

public class User implements Serializable {
    private static final long serialVersionUID = 1L;//序列化版本号
    private int age;
    private String name;


    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
public class User1 implements Externalizable{
    private int age;
    private String name;

    public User1() {
    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

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

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeInt(age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String)in.readObject();
        age = in.readInt();
    }
}

3.那么这两种方式有什么区别呢?

个人认为通过实现Serializable接口实现序列化的话会将对象的中的全部成员变量全部序列化,想要某个成员不被序列化的需要通过transient关键字修饰相应的成员变量避免序列化。而实现Externalizable接口则是可以按照自己的想法序列化特定的成员变量,因为Externalizable是通过重写writerExternal和readExternal方法来实现序列化的。

看上面例子的重写方法就知道了

@Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeInt(age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String)in.readObject();
        age = in.readInt();
    }

除此之外,Externalizable接口反序列化是通过调用相应类的默认构造方法生成对象的,所以实现Externalizabl除了需要实现相应的方法还得保证类有一个默认的构造方法,而Serializable则不是通过调用相应构造函数生成对象的,有兴趣的朋友可以网上百度一波。

还有一个问题就是通过反序列生成的对象跟原来的对象并不是同一个,所以一个单例模式类需要实现序列化接口的话还需要在类中写一个readResolve无参的方法。

本人知识水平有限,文中难免有错漏的地方,还望各位读者多多海涵。

你可能感兴趣的:(java基础之序列化)