为什么使用 Parcelable, 好处是什么?
这道题想考察什么?
JDK本身提供了Serializable序列化接口,为什么Android还要设计Parcelable?Parcelable相对于Serializable的区别是什么?它的实现原理又是什么?
考察的知识点
序列化与反序列化
考生如何回答
什么是序列化?
首先我们要了解什么是序列化?序列化是将对象的状态信息转换为可以存储或传输的形式的过程,序列化最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性。
就相当于我们现在要把埃菲尔铁塔完全一摸一样的搬到北京,实现这个过程就是序列化的过程。我们需要给埃菲尔铁塔的每个部件都打上标记,这个钢筋部件原来在哪个位置,搬到北京后仍然要在对应的位置。这就是将埃菲尔铁塔序列化了之后传输(运输)到北京。而反序列化自然就是利用运到北京的部件根据标记信息还原的过程。
Serializable的原理
那么JDK当中实现的Serializable序列化接口是如何将一个对象进行序列化的?
static class SerializableTest implements Serializable {
int i;
long j;
public SerializableTest(int i, int j) {
this.i = i;
this.j = j;
}
@Override
public String toString() {
return "SerializableTest{" +
"i=" + i +
", j=" + j +
'}';
}
}
@Test
public void testSerialible() throws IOException, ClassNotFoundException {
SerializableTest serializableTest = new SerializableTest(1, 2);
//序列化
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream("SerializableTest"));
os.writeObject(serializableTest);
os.close();
//反序列化
ObjectInputStream is = new ObjectInputStream(new FileInputStream("SerializableTest"));
SerializableTest serializableTest1 = (SerializableTest) is.readObject();
System.out.println(serializableTest1);
}
对于JVM来说,要进行持久化的类必须要有一个标记,只有持有这个标记JVM才允许类创建的对象可以通过其IO系统转换为字节数据,从而实现持久化,而这个标记就是Serializable接口。而在反序列化的过程中则需要使用serialVersionUID来确定由哪个类来加载这个对象,如果我们在序列化中没有显示地声明serialVersionUID,则序列化运行时将会根据该类的各个方面计算该类默认的serialVersionUID值。 但是,Java官方强烈建议所有要序列化的类都显示地声明serialVersionUID字段,因为如果高度依赖于JVM默认生成serialVersionUID,可能会导致其与编译器的实现细节耦合,为了保证跨不同Java编译器实现的serialVersionUID值的一致,实现Serializable接口的必须显示地声明serialVersionUID字段。
总之实现了Serializable接口就相当于给类打上了一个标记,JVM就能够对类对象信息按照(Serializable)规则记录,而反序列化就按照规则解析即可。
Parcelable的原理
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
//序列化
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
//反序列化
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
我们通过Serializable的使用可以发现,Serializable需要使用IO对序列化数据直接写入到文件当中。而Parcelable是android特有的序列化方式,我们在开发中可能并不需要将数据保存到文件当中,只在内存中进行传输使用,此时使用Parcelable将更为高效,因为Parcelable依赖于Parcel,Parcel的意思是包装,实现原理是在内存中建立一块共享数据块,序列化和反序列化均是操作这一块的数据,而不像Serializable需要使用IO。
image.png对比
- Serializable是java序列化的方式,存取的过程有频繁的IO,性能较差,但是实现简单。
- Parcelable是android序列化的方式,采用共享内存的方式实现用户空间和内核空间的交换,性能很好,但是实现方式比较复杂。
- Serializable可以持久化存储,Parcelable是存储在内存中的,不能持久化存储。
最后
有需要面试题的朋友可以关注一下哇哇,以上都可以分享!!!
网友评论