Java序列化

维基百科上对于序列化的解释是保存数据为可被取用的格式,而反序列化就是指取用这些数据。把文本复制到电脑的剪切板,把各种文件保存到硬盘都可被称为序列化

序列化指的是保存数据的过程,所以实现Serializable、Parcelable接口不是序列化,而是让对象可以被序列化

Java中的序列化指的是把数据保存为可被其他进程读取的格式,Java的序列化相关的类把数据以某种格式保存,而其他进程可以用这些类把数据读取出来,相当于是一种数据写入读取的协议,如果每个应用程序都自己来实现序列化那将很乱且不通用,所以使用Java提供的序列化方式

序列化是针对对象的,而静态成员变量属于类而不是属于对象,所以静态成员变量不参与序列化

Serializable

Java 提供的序列化方法,不推荐在android中使用
使用方法很简单,只需要实现这个Serializable接口即可,而它也没有什么需要实现或覆盖的方法,只要定义一个long常量即可
private static final long serialVersionUID = 一个数字;

这种序列化的方式不推荐使用,所以我也不写什么demo,这里只解答几个问题

0 为什么需要serialVersionUID

这个值相当于是一个校验码,反序列化的时候比较当前类中的serialVersionUID和序列化数据中的serialVersionUID,如果相同,则反序列化成功,否则失败

静态成员变量不参与序列化,而serialVersionUID参与序列化,这两个说法都来自《android开发艺术探索》,好像有矛盾。我的理解是这是【静态常量】不是【静态变量】,所以它参与序列化,亦或者是因为需要用它做校验?

serialVersionUID的值可以手动指定,随便什么值,也可以用集成开发环境生成的值(如果这个集成开发环境有这个功能的话),没什么区别

如果不设置serialVersionUID

在序列化和反序列化的时候,如果不手动指定serialVersionUID,系统会自动计算这个值,如果序列化存储期间,这个实现Serializable的类被重新编辑(删除或增加成员变量),反序列化的时候计算出来的serialVersionUID值就与原先的不同,导致反序列化失败
如果手动设置这个值,这个类虽然发生了变化,系统还是会反序列化这个对象,尽可能的恢复保存的数据,虽然不可能恢复到被保存的状态了

1 实现这个接口后如何序列化

使用ObjectOutputStream把实现这个接口的对象写入一个文件,就是序列化;用ObjectInputStream把这个文件读取成一个对象,就是反序列化。当然,反序列化的时候需要知道那个文件的路径

2 为什么不推荐这个方式

由上一题可知这种序列化方式伴随大量io操作,效率很低

3 在bundle中使用Serializable为什么不需要序列化

bundle会自动序列化和反序列化Serializable对象,省去了手动将对象写入文件的过程,虽然我没找到这个序列化的具体代码
确切的说bundle会序列化它保存的所有数据,不只是Serializable、Parcelable,还包括其他基本类型

Parcelable

Parcelable是在内存上序列化,当然也可以把对象序列化到存储设备或者同伙网络传输,但是这两种情况下用Parcelable会比较复杂,推荐使用Serializable

Parcelable对象是可被序列化的对象
Parcel对象是保存Parcelable对象序列化后的数据的容器,它可以在进程间传递,Parcelable则不行

demo如下

public class MyP implements Parcelable {
    private String str1;
    private String str2;

    public MyP(String str1, String str2) {
        this.str1 = str1;
        this.str2 = str2;
    }

    public String getStr1() {
        return str1;
    }

    public String getStr2() {
        return str2;
    }

    //这下面就是要实现的东西,
    public static final Creator<MyP> CREATOR = new Creator<MyP>() {
        //在这里返回一个【我自定义的实现Parcelable接口】的对象
        //调用Parcel的read方法实现反序列化
        @Override
        public MyP createFromParcel(Parcel in) {
            return new MyP(in.readString(),in.readString());
        }
        //这个方法不用改,用系统默认的就行
        @Override
        public MyP[] newArray(int size) {
            return new MyP[size];
        }
    };
    //用一个int值描述当前的Parcelable类型,不用管,直接返回0  
    @Override
    public int describeContents() {
        return 0;
    }
    //调用Parcel的write方法实现序列化
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str1);
        dest.writeString(str2);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值