什么是序列化?
将数据结构或者对象转换成二进制串的过程
序列化的方案有哪些?
- Serializable (java)
- Externaliable (
下面两个方法在读写的属性时需要成双成对使用,不能在不写属性的情况下去读这个属性;并且读写的顺序都必须保持一致;并且还要由一个无参的构造函数
)- writeExternal(ObjectOutput oo)
- readExternal(ObjectIntput oi)
- Externaliable (
- Parcelable (Android)
- json、xml、protobuf? 二进制数据
关于序列化的几个问题?
- 什么是
serialVersionUID
?如果不定义这个,会发生什么?
是对象的一个常量,通常是对象的
hashCode
,用于对象的版本控制.
如果不添加serialVersionUID
,当对象的属性添加或者删除的时候,则已经序列化的对象将无法更新.
- 序列化时,如果希望某些成员不被序列化?应当如何实现?什么是瞬态
transient
?
如果我们希望某个成员不被序列化时,可以采用
transient
修饰这个变量,(或者将这个变量定义成)静态
变量,这个有争议,我试过,定义成static的变量,仍然会被序列化
- 如果一个类的成员类未实现可序列化接口,会发生什么?
会报错
NotSerializableException
- 如果当前类实现了序列化,但是它的父类没有实现序列化,那么反序列化后从父类继承的实例变量的状态如何?
子类实现了序列化,父类没有实现,那么从父类继承的实例变量都是默认值.
怎么避免上面的问题呢?
- 可以在子类中重写writeObject和readObject方法,在这两个方法中读写父类的属性.
- 也可以让父类实现序列化
- 如果父类实现了序列化,子类继承了父类,默认也是会实现序列化的,那么怎么避免子类被序列化呢?
可以重写子类的
writeObject
和readObject
方法.
- 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框架用到了哪些设计模式?
-
Gson框架使用到了
适配器设计模式
(TypeAdapter)
json字符串->TypeAdapter->JavaBean
JavaBean->TypeAdapter->json字符串 -
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