「序列化」是将对象转换为可以存储或传输的格式的过程。在计算机科学中,对象通常是指内存中的数据结构,如数组、列表、字典等。通过序列化,可以将这些对象转换为字节流或文本格式,以便在不同的系统之间进行传输或存储。序列化后的数据可以被传输到远程系统,或者存储在磁盘上,以便在需要时进行读取和恢复。序列化的逆过程称为反序列化,即将序列化后的数据重新转换为原始对象的过程。
「反序列化」是将序列化后的数据恢复为原始对象的过程。在编程中,我们经常需要将对象序列化为字节流或者其他形式的数据,以便在网络传输或者持久化存储中使用。而反序列化则是将这些序列化后的数据重新转换为原始对象。
在不同的编程语言中,反序列化的实现方式可能会有所不同。一般来说,反序列化的过程包括以下几个步骤:
反序列化的过程可以用以下伪代码表示:
data = 读取序列化后的数据
object = 解析数据(data)
在实际应用中,反序列化的方式和具体实现会根据编程语言和序列化库的不同而有所差异。不同的序列化格式有不同的特点和适用场景,开发者可以根据具体需求选择合适的序列化方式。
Android数据对象序列化的主要用途是将对象转换为字节流的形式,以便在网络传输、持久化存储或进程间通信中使用。具体的用途包括:
序列化提供了一种方便的方式来在不同的场景中传输和存储对象数据。它在网络传输、持久化存储和进程间通信等方面都有广泛的应用。
在Android中,常用的实现对象序列化有以下几种方式:
(1) 实现Serializable接口:在需要序列化的类中实现Serializable接口,该接口没有任何方法,只是作为一个标记接口。然后使用ObjectOutputStream将对象写入输出流,使用ObjectInputStream从输入流中读取对象。示例代码如下:
public class MyClass implements Serializable {
// 类的成员变量和方法
public static void mAIn(String[] args) {
// 序列化对象
MyClass obj = new MyClass();
try {
FileOutputStream fileOut = new FileOutputStream("object.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(obj);
out.close();
fileOut.close();
System.out.println("对象已序列化");
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化对象
MyClass newObj = null;
try {
FileInputStream fileIn = new FileInputStream("object.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
newObj = (MyClass) in.readObject();
in.close();
fileIn.close();
System.out.println("对象已反序列化");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
(2) 实现Parcelable接口:Parcelable接口是Android特有的接口,相比Serializable接口,它更高效。在需要序列化的类中实现Parcelable接口,并实现相关方法。然后使用Parcel对象将对象写入Parcel,使用Parcel对象从Parcel中读取对象。示例代码如下:
public class MyClass implements Parcelable {
// 类的成员变量和方法
protected MyClass(Parcel in) {
// 从Parcel中读取数据并赋值给成员变量
}
public static final Creator<MyClass> CREATOR = new Creator<MyClass>() {
@Override
public MyClass createFromParcel(Parcel in) {
return new MyClass(in);
}
@Override
public MyClass[] newArray(int size) {
return new MyClass[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// 将成员变量写入Parcel
}
}
(3) 使用Gson库:Gson是google提供的一个用于在JAVA对象和JSON数据之间进行序列化和反序列化的库。可以使用Gson将对象转换为JSON字符串,然后再将JSON字符串转换为对象。示例代码如下:
public class MyClass {
// 类的成员变量和方法
public static void main(String[] args) {
// 序列化对象
MyClass obj = new MyClass();
Gson gson = new Gson();
String json = gson.toJson(obj);
System.out.println("对象已序列化为JSON字符串:" + json);
// 反序列化对象
MyClass newObj = gson.fromJson(json, MyClass.class);
System.out.println("JSON字符串已反序列化为对象");
}
}
「Serializable」是Java中的一个接口,用于实现对象的序列化和反序列化。序列化是指将对象转换为字节流的过程,而反序列化则是将字节流转换为对象的过程。
Serializable接口没有任何方法,它只是一个标记接口,用于告诉Java虚拟机,该类可以被序列化。要实现序列化,只需要让类实现Serializable接口即可。
在序列化过程中,Java虚拟机会将对象的状态转换为字节序列,然后可以将字节序列保存到文件、数据库或通过网络传输。反序列化过程则是将字节序列重新转换为对象的状态。
在序列化过程中,Java虚拟机会对对象的各个字段进行序列化。对于基本类型和引用类型,Java虚拟机会自动进行序列化。对于自定义类型,需要实现Serializable接口,并且保证该类型的所有成员变量也是可序列化的。
在反序列化过程中,Java虚拟机会根据字节序列重新创建对象,并将字节序列中的数据赋值给对象的各个字段。
需要注意的是,序列化和反序列化的过程中,对象的构造函数不会被调用。因此,在反序列化过程中,如果需要进行一些初始化操作,可以使用特殊的方法readObject()来实现。
总结起来,Serializable接口提供了一种简单的方式来实现对象的序列化和反序列化。通过实现Serializable接口,可以将对象转换为字节序列,以便在不同的环境中进行传输和存储。
「Parcelable」是Android中用于实现对象序列化的接口。它的原理是将对象的数据按照一定的格式进行打包和解包,以便在不同的组件之间传输或存储。
具体实现步骤如下:
通过实现Parcelable接口,可以将对象的数据打包成一个Parcel对象,然后可以通过Intent传递给其他组件,或者通过Bundle存储到本地。在接收端,可以通过读取Parcel对象的数据,重新构建出原始的对象。
总结起来,Parcelable的原理就是将对象的数据按照一定的格式进行打包和解包,以实现对象的序列化和反序列化。这种方式相对于Java中的Serializable接口,更加高效和灵活。
Serializable和Parcelable都是用于实现对象的序列化和反序列化的接口,但在实现方式和性能方面有所不同。
(1) Serializable:
(2) Parcelable:
Serializable适用于简单的序列化场景,而Parcelable适用于对性能要求较高的Android平台。在选择使用Serializable还是Parcelable时,需要根据具体的需求和性能要求进行权衡。
数据来自parcelable-vs-serializable,实验结果对比Parcelable的效率比Serializable快10倍以上。
对比 |
Serializable |
Parcelable |
所属API |
Java API |
Android SDK API |
特点 |
序列化和反序列化会经过大量的I/O操作,产生大量的临时变量引起GC,且反序列化时需要反射 |
基于内存拷贝实现的封装和解封(marshalled& unmarshalled),序列化基于Native层实现 |
开销 |
相对高 |
相对低 |
效率 |
相对低 |
相对高 |
适用场景 |
简单序列化 |
Android |
在使用「Serializable」进行对象的序列化时,有一些注意点需要注意:
在使用「Parcelable」进行序列化时,有几个注意点需要注意:
使用Parcelable进行序列化时,需要确保实现了Parcelable接口,并注意序列化顺序、内部类的序列化、数据类型的一致性和版本控制等问题。