一. serializable 的作用
利用ObjectInputStream和ObjectOutputStream将一个对象的类信息,方法信息,属性信息和数据读取/写入到二进制字节流中.
二. serializable 使用的必要条件
- 必须实现serializable接口
- 必须提供无参数构造方法
三. serializable一些常见问题
3.1 假设你有一个类,他序列化并存储在持久性中,然后修改了该类以添加新字段。如果对已序列化的对象进行反序列化会发生什么情况?
如果没有修改serialVersionUID,会报invalidClassException,如果有修改,则可以正常序列化
3.2 序列化时,你希望某些成员不要序列化?你如何实现它?
定义为transient 或者定义为static.
3.3 如果类中的一个成员未实现可序列化接口,会发生什么情况?
报错,内部成员未实现serializable,可以将成员标记为transient.
3.4 如果类是可序列化的,但其超类不是,可以序列化吗,则反序列化后从超类继承的实例变量状态如何?
可以正常序列化,但是要提供默认构造方法.且超类集成的实例变量会被赋予默认值.
3.5 为什么序列化一定需要一个无参构造?
在反序列化过程中,构造对象会通过反射构造,需要一个无参构造方法.
3.6 是否可以自定义序列化过程,或者覆盖JAVA中默认的序列化过程?
可以.实现readObject或者writeObject方法,自己定义要写入或者读出的属性.
private void writeObject(java.io.ObjectOutputStream s) throws IOException
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException
3.7 假设子类的超类实现可序列化接口,子类如何避免序列化?
标记为transient,定义为static,或者重写writeObject方法
3.8 在java中的序列化和反序列化过程使用哪些方法?
-
序列化:ObjectOutputStream.writeObject
-
反序列化:ObjectInputStream.readObject
3.9 ObjectStreamClass / readObject / writeObject / serialVersionUID
- ObjectStreamClass:代表被序列化的对象的信息
- writeObject/readObject:在序列化和反序列化过程中通过反射调用的方法,用于可以让开发者干预过程.
- serialVersionUID:为版本兼容做处理,根据serialVersionUID是否变化来确定如何处理新增,删除,变化的属性和方法.
四.Parcelable
- 区别于Serializable这个oracle实现的对象序列化技术,Parcelable是google提供的一套用于在android系统中进程间通信的序列化技术.
- Parcelable通过binder机制(后续篇章继续分析)传输相同的parcel对象,借助parcel的read和write方法,从而实现序列化和反序列化.
- 不同于Serializable将序列化过程全部隐藏到ObjectStreamClass中 , Parcelable显示的要求开发者定义好要序列化的属性和顺序(可以一键生成),具有更好的灵活性.
- Parcelable相比于Serializable,由于采用mmap共享内存传输数据,同时不用反射来读取数据,因此速度显著高于Serializable.Serializable传输的数据主要用于io,没有大小限制,Parcelable受限于binder的缓冲区的大小,最大不超过1m/2m/4m.