最近有个大众号粉丝和我聊了聊他面试的经历,一个刚入坑Android两年的新人,因为异地的原因视频面试,而面试官只问了一个问题:“JDK自身供给了Serializable序列化接口,为什么还要运用 Parcelable
?”,结果他一时语塞面试OVER
。说实话听到这个问题,我也有些懵逼,平常忙着研讨各种组件、什么高可用框架,可真要回头对Java根底知识较起真,发现自己的技术债欠的太多,所以和咱们一同复习一下Java
序列化知识。
回忆
什么是序列化?
首要咱们要了解什么是序列化?序列化是将目标的状态信息转换为能够存储或传输的形式的进程,序列化最主要的用途便是在传递和保存目标的时分,保证目标的完整性和可传递性。
就相当于咱们现在要把埃菲尔铁塔彻底一摸一样的搬到北京,完成这个进程便是序列化的进程。咱们需要给埃菲尔铁塔的每个部件都打上符号,这个钢筋部件本来在哪个位置,搬到北京后仍然要在对应的位置。这便是将埃菲尔铁塔序列化了之后传输(运输)到北京。而反序列化自然便是利用运到北京的部件依据符号信息复原的进程。
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。
对比
- Serializable是java序列化的方法,存取的进程有频繁的IO,功能较差,可是完成简略。
- Parcelable是android序列化的方法,采用同享内存的方法完成用户空间和内核空间的交换,功能很好,可是完成方法比较复杂。
- Serializable能够耐久化存储,Parcelable是存储在内存中的,不能耐久化存储。
今天分享到此结束,对你有帮助的话,点个赞再走呗,好像写的有点浅,咱们凑合看下吧,下期更精彩~
重视大众号:Android老皮
解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已构成PDF版
内容如下:
1.Android车载应用开发体系学习指南(附项目实战)
2.Android Framework学习指南,助力成为体系级开发高手
3.2023最新Android中高级面试题汇总+解析,离别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨渠道首要之选
7.Kotlin从入门到实战,全方面提高架构根底
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 功能优化实战+360全方面功能调优
10.Android零根底入门到精通,高手进阶之路
敲代码不易,重视一下吧。ღ( ・ᴗ・` )