Android序列化、反序列化


继承是在子类对象中持有一个指向父类对象的引用,super。也就是说,在Java内部,继承是通过隐式的组合实现的。在实际的方法调用中,java会优先在当前类对象中寻找名称相同的方法,如果没有,进而根据super引用到父类对象中去寻找,所以,如果父类方法在子类中得到重写,java会调用子类的方法,而不会调用被重写的父类方法,这也是多态的实现机制。(如果基类和派生类有同名的成员变量,多态机制下取的是基类的成员变量值,成员变量没有重写的概念?)

对象作为参数传递,其实只是传递对象的引用(指针)。

到这里,基本就明白了,内存传来传去的都是地址而已。

跨进程通讯,网络传输,传递对象,(对象是内存中的一个地址引用,跨进程,跨网络,是无法取到的,所以需要序列化、反序列化)

1、序列化作用:
  • 持久化存储,保持到本地存储介质
  • 网络传输
  • IPC(Inner-process communication)进程间传递

Android中序列化和反序列化的方式:实现Serializable和parcelable接口

2、Serializable接口

是Java提供的一种序列化方式

  • 序列化之前和反序列化之后的对象不是同一个对象,值一样
  • 序列化时,只对对象的状态进行保存,而不管对象的方法
  • 当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口
  • 当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化
  • Serializable通过Transient关键字修饰的字段,不进行序列化,反序列化取出来的是默认值(null/0/false)
  • 序列化的时候会产生大量的临时变量,从而引起频繁的GC。
  • 适用于持久化存储、数据库、网络流传递

序列化时,通过 ObjectOutputStream 将对象直接输出存储到本地,需要用的时候,通过反射新建一个对象,然后通过 ObjectInputStream 从本地读取流,给对象的每一个field赋值。相当于创建了一个新对象,值一样。

参考:
java基础---->Serializable的使用
java高级---->Serializable的过程分析

拓展:

Java对象序列化为什么要使用SerialversionUID?

  • SerialversionUID作为唯一ID,进行序列化和反序列化的参照
  • 如果没有指定SerialversionUID,系统会自动生成一个SerialversionUID(和类强相关)
  • 反序列化时,如果类发生了改变,会抛出InvalidClassException
  • 所以强烈建议用户自定义一个SerialversionUID
3、Parcelable接口

既然有了serializable接口,为什么android还要单独设计Parcelable接口呢?
因为serializable是通过流的方式,频繁读写,会创建很多的临时变量,效率不高。设计出来Parcelable接口,基于Android平台的特性,用于Android不同组件之间的通讯,以及不同进程之间的通讯。

Android开发的时候,Intent在启动其他组件时,会离开当前应用程序进程,进入ActivityManagerService进程(intent.prepareToLeaveProcess()),这也就意味着,Intent所携带的数据要能够在不同进程间传输。Android是基于Linux系统,不同进程之间的java对象是无法传输,所以我们此处要对对象进行序列化,从而实现对象在 应用程序进程 和 ActivityManagerService进程之间传输。

Android系统用户空间不共享内存,内核控件是共享内存的。
parcelable实现原理是在内核空间开辟一块共享内存,序列化和反序列化都是操作这一块的数据。

  • 整个读写全是在内存中进行,所以效率比Serializable高
  • 不能使用在要将数据存储在磁盘上的情况,只适用于内存传递(IPC)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值