7.序列化Serializable

什么是序列化?

将数据结构或者对象转换成二进制串的过程

序列化的方案有哪些?

  • Serializable (java)
    • Externaliable (下面两个方法在读写的属性时需要成双成对使用,不能在不写属性的情况下去读这个属性;并且读写的顺序都必须保持一致;并且还要由一个无参的构造函数)
      • writeExternal(ObjectOutput oo)
      • readExternal(ObjectIntput oi)
  • Parcelable (Android)
  • json、xml、protobuf? 二进制数据

关于序列化的几个问题?

  1. 什么是serialVersionUID?如果不定义这个,会发生什么?

是对象的一个常量,通常是对象的hashCode,用于对象的版本控制.
如果不添加serialVersionUID,当对象的属性添加或者删除的时候,则已经序列化的对象将无法更新.

  1. 序列化时,如果希望某些成员不被序列化?应当如何实现?什么是瞬态transient?

如果我们希望某个成员不被序列化时,可以采用transient修饰这个变量,(或者将这个变量定义成静态变量,这个有争议,我试过,定义成static的变量,仍然会被序列化)

  1. 如果一个类的成员类未实现可序列化接口,会发生什么?

会报错NotSerializableException

  1. 如果当前类实现了序列化,但是它的父类没有实现序列化,那么反序列化后从父类继承的实例变量的状态如何?

子类实现了序列化,父类没有实现,那么从父类继承的实例变量都是默认值.
怎么避免上面的问题呢?

  • 可以在子类中重写writeObject和readObject方法,在这两个方法中读写父类的属性.
  • 也可以让父类实现序列化
  1. 如果父类实现了序列化,子类继承了父类,默认也是会实现序列化的,那么怎么避免子类被序列化呢?

可以重写子类的writeObjectreadObject方法.

  1. java中序列化和反序列化都用到了哪些方法?

readObject() writeObject() readExternal() writeExternal().
java的序列化由ObjetOutputStream类完成

序列化流程?

ObjectOutputStream->writeObject->writeObject0->writeOrdinaryObject->writeSerialData->defaultWriteFields

Serializable和Parcelable区别?

  • Serializable
    通过IO对硬盘操作,速度较慢
    传递数据大小不受限制
    大量使用反射,产生内存碎片
  • Parcelable
    直接在内存操作,效率高,性能好
    传递数据一般不能超过1M(受到进程间通信binder影响),修改内核也只能达到4M

面试相关
1. 反序列化后的对象,需要调用构造函数重新构造吗?
不需要,反序列化是将二进制串转换成对象的过程,直接将我们反序列化的对象进行强转就能得到我们的对象.

2. 序列化的对象和反序列化后的对象是一个什么样的关系?(是==还是equlas,是浅拷贝还是深拷贝?)
equals,深拷贝 (枚举列外)

3. Android里面为什么要设计出Binder而不直接使用Map?
参考Binder源码解析

4. SerialVersionUID的作用是什么?
用来做版本控制,防止新增属性后,造成反序列化解析失败.

5. Android中Intent/Bundle的通信原理和大小限制?
参考Binder源码解析

6. 为什么Intent不能直接在组件间传递对象而要通过序列化机制?
参考AMS源码解析

序列化和持久化的关系和区别是什么?
序列化是为了实现进程间数据的交互,而持久化是为了数据的存储与使用.

Json是什么?
是一种轻量级的数据交换格式(JavaScript Object Notation)
用来做数据标记、数据存储和数据传输.

Gson中比较重要的几个类

  • TypeAdapter (可以用来自定义解析器)
  • JsonWriter (将对象转换成字符串)
  • JsonReader (将字符串转换成对象)

解决后端返回json数据不规范问题,比如一个JavaBean对象类型,在没有数据的情况下后端直接返回“”,而不返回null

  • 使用自定义TypeAdater,在解析read()的时候做处理,在JsonReader读到的每一个数据时候做处理
  • 使用自定义JsonDeserializer,在解析deserialize()的时候,对返回的一个个数据JsonElement做处理,判断到我们的那个key(如:person)时,如果他的值是“”,那么将他的值改为null

Gson框架用到了哪些设计模式?

  1. Gson框架使用到了适配器设计模式(TypeAdapter)
    json字符串->TypeAdapter->JavaBean
    JavaBean->TypeAdapter->json字符串

  2. Gson框架使用到了门面设计模式
    下面代码中的fromJson和toJson方法都是用到了门面设计模式,将复杂的功能封装在了内部.

Gson gson = new Gson();
gson.toJson(person);
gson.fromJson(jsonString, Person.class);

Gson构造函数解析(一部分)

  • Excluder 排除器,用来处理注解,如Since,Until,Expose
  • FieldNamingStrategy 属性命名策略,用来处理注解,如SerializedName
  • List factories 解析器集合,
    • 最开始添加排除器
    • 然后添加用户自定义的解析器
    • 接着添加一些基本数据类型解析器
    • 最后添加反射解析器ReflectiveTypeAdapterFactory

Json字符串解析成JavaBean流程是怎样的?
json字符串->排除器->自定义的TypeAdapter->Gson自带的TypeAdapter->反射ReflectiveTypeAdapter->JavaBean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值