Serializable接口心得总结

       Serializable是Java提供的序列化接口,是一个空接口,为对象提供标准的序列化与反序列化操作。使用Serializable实现序列化过程相当简单,只需要在类声明的时候指定一个标识,便可以自动的实现默认的序列化过程。

private static final long serialVersionUID = 1L;

       上面已经说明让对象实现序列化,只需要让当前类实现Serializable接口,并且声明一个serialVersionUID就可以了,非常的简单方便。实际上serialVersionUID都不是必须的,没有它同样可以正常的实现序列化操作。

      User类就是一个实现了Serialzable的类,它是可以被序列化和反序列化的。

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private String userId;
    private String userName;

}

       通过Serializable实现对象的序列化过程非常的简单,无需任何操作,系统就为我们自动实现了。如何进行对象的序列化与反序列化操作也是非常的简单,只需要通过ObjectOutputStream,ObjectInputStream进行操作就可以了。

 //序列化过程
    public void toSerial() {
        try {
            User user = new User("id", "user");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("user.txt"));
            objectOutputStream.writeObject(user);
            objectOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //反序列化过程
    public void fromSerial(){
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("user.txt"));
            User user = (User) objectInputStream.readObject();
            objectInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

       是的,你没有看错,序列化与反序列化操作过程就是这么的简单。只需要将User写入到文件中,然后再从文件中进行恢复,恢复后得到的内容与之前完全一样,但是两者是不同的对象。当然了前面提到过一个问题,如果将serialVersionUID去掉会产生什么样的影响呢? 

       刚开始提到了,serialVersionUID要不要指定呢?如果不指定会出现什么样的后果?如果指定了以后后边的值又代表着什么意思呢?同时我们也要明白,既然系统指定了这个字段,那么肯定是有它的作用的。

       这个serialVersionUID是用来辅助对象的序列化与反序列化的,原则上序列化后的数据当中的serialVersionUID与当前类当中的serialVersionUID一致,那么该对象才能被反序列化成功。这个serialVersionUID的详细的工作机制是:在序列化的时候系统将serialVersionUID写入到序列化的文件中去,当反序列化的时候系统会先去检测文件中的serialVersionUID是否跟当前的文件的serialVersionUID是否一致,如果一直则反序列化成功,否则就说明当前类跟序列化后的类发生了变化,比如是成员变量的数量或者是类型发生了变化,那么在反序列化时就会发生crash,并且回报出错误:

       我这个操作的流程是:首先在手机sd卡的根目录创建一个文件user.txt,在创建的时候做出判断,如果user.txt不存在,则进行创建文件操作并进行序列化写入操作。如果user.txt存在那么我们就直接读取并进行反序列化操作。我在创建完成后,在User里面多加了一个属性,然后在进行反序列化操作的时候就报出了这样的错误,当然前提是我把类中声明的serialVersionUID去掉了。 

       当我把serialVersionUID加上的时候,我在创建完user.txt后我在进行序列化读取,成功的拿到了之前存进去的数据。这样的一个操作过程就让我们很清楚的看出来了serialVersionUID在序列化与反序列化过程当中的作用。

       这个字段的作用显而易见,加入我们升级了系统,在User当中增加了字段属性,那么我们在手动添加了serialVersionUID之后,我们在进行序列化和反序列化的时候就会很从容,就不会再出现crash的情况了。

       另外强调两点,静态成员变量属于类不属于对象所以不参与序列化的过程,还有如果使用transient标记的成员变量不参与序列化过程。

阅读更多
换一批

没有更多推荐了,返回首页