7.Serializable和Parcelable
来源:互联网 发布:java ping 域名是否通 编辑:程序博客网 时间:2024/05/16 02:16
Serializable和Parcelable接口可以完成对象的序列化过程,当我们需用使用Intent 和Binder 传输数据的时候,就需要使用到Parcel和Serializable.而有时候,我们需要持久化数据、或者是传输数据到网络上,我们也要使用Serializable来完成对象的序列化。
7.1Serializable接口
实现序列化接口,很简单,只需要实现它,就好,当然,最好是赋予它一个serialVersionUId (序列化ID)。不声明序列化ID,其实也可以序列化,但是,可能会对反序列化有影响。下面我们就简单介绍序列化和反序列化的过程:
假设我们有一个User类如下:
public class User impelements Serializable{ private static final long serialVersionUID = 519606712346586214L; public int userId; public String userName; }
序列化过程需要用到ObjectOutputStream下面是序列化的过程:
User user = new User(); user.userId= 12; user.userName = "张三"; ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream( "cache.txt") ); out.writeObject( user ); out.close();
通过上面的代码,对象就序列化到了cache.txt文件上了。
而这时候,我们希望能够把文件在变成对象,该怎么做呢?
就要进行反序列化过程,序列化的过程我们是使用ObjectOutputStream 那么反序列化当然是用ObjectInputStream
ObjectInputStream in = new ObjectOutputStream( new FileInputStream( "cache.txt")); in.readObject(); in.close();
通过上面的代码,我们就能把对象从文件当中恢复,恢复出来的内容是完全一样的,但是他们不是同一个对象。
现在,我们在这边来讨论下serialVersionUID的作用吧,首先,就要从反序列化过程入手:
反序列化的时候,系统会查看文件的序列化ID,如果序列化ID一致,那么就会进行序列化,因为这代表对象是一样的,反之,则不会,因为序列化ID不一样说明了这个类已经被改变了,比如成员数量变化、类型变化,这时候就会反序列化失败。一般来说,我们要手动指定UID值,或者是用Eclipse等工具在创建的时候自动生成一个hash值,如果我们不指定会怎么样?不指定的话,系统序列化的时候,会把当前类的hash值作为序列化ID,那么当我们反序列化的时候,如果这个类改变了,那么hash值就会改变,那么就会造成序列化ID不一样,那么就导致了反序列化失败。
简单地说,不指定ID的话,我们存储User 时候有2个变量,而我们想获取原来User的数据的时候,我们改变了User类,改成了3个变量.增加了学号:number
这时候,从cache.txt想反序列化是不行的,因为cache的那个User是2个变量的User ,2个变量的User和3个变量的User的hash值改变了,所以系统认为两个不是一个版本的类,所以反序列化失败。
值得一提的是,序列化ID一样,并不一定会保证反序列化成功,比如我把userName从String改成了int,这样就会破坏了类的结构,或者是我改了类名也会造成这种情况。
7.2Parcelable接口
Parcelable也是一个接口,只要实现这个接口,这个类的对象就可以实现序列化,并且可以通过Intent和Biner进行传递。
下面是实现了Parcelable的例子:
public class User implements Parcelable { public int userId; public String userName; public boolean isMale; public Book book; public User( int userId, String userName , boolean isMale ) { this.userId = userId; this.userName = userName; this.isMale = isMale; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int arg1) { out.writeInt( userId ); out.writeString(userName); out.writeInt( isMale ? 1:0 ); out.writeParcelable(book, 0); } public Parcelable.Creator< User> CREATOR = new Parcelable.Creator<User>() { @Override public User createFromParcel(Parcel arg0) { return new User(arg0) ; } @Override public User[] newArray(int arg0) { // TODO Auto-generated method stub return new User[arg0]; } }; private User( Parcel in ) { userId = in.readInt(); userName = in.readString(); isMale = in.readInt() == 1 ? true : false; book = in.readParcelable( Thread.currentThread().getContextClassLoader()); }}
可以看到,反序列化的过程是由CREATOR来实现的。
系统已经为我们提供了很多实现了Parcelable的类,它们都是可以直接序列化的,比如Intent、Bundle、Bitmap等,
同时List和Map也可以序列化,前提是它们里面的每个元素都是可以序列化的。
Serializable是Java的接口,它使用起来比较简单,但是开销大,因为需要大量的I/O操作。而Parcel是Anroid多肚饿,他的效率比较高,适合用在内存交换当中,而如果是持久化数据或者是网路传输,采用Serializble比较好,因为Parcel实现比较复杂(也是可以持久化和传输)。
0 0
- 7.Serializable和Parcelable
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- android: Serializable 和 Parcelable
- android86--Parcelable 和Serializable
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- Serializable 和 Parcelable 区别
- serializable和parcelable
- Meanshift
- 34. Swap Nodes in Pairs
- Activiti5工作流 笔记(2)--创建工作流引擎
- 第一个Java程序
- Spring高级应用之注入各类集合
- 7.Serializable和Parcelable
- LokiJS入门demo1
- linux下Intel TBB、 Open MPI、OpenMP
- UFLDL 06 PCA 主成分分析法
- 文章标题
- 最好用的Nema信号模拟器:NemaStudio 1.30.5885 开发者Nema 必备利器, 包括AIS Simulator,GPS Simulator,weather simulator,ra
- codeforces 662D International Olympiad
- LAMP环境安装之CentOS(一)
- 8.Binder详解