Android面试题详解之序列Parcelable,Serializable的区别?

序列Parcelable,Serializable的区别?(阿里)

详细讲解

架构师筑基必备技能《NDK专题-JNI实战篇》

这道题想考察什么?

掌握序列化接口实现原理,针对不同场景在工作中合理运用

考察的知识点

Parcelable原理

Serializable原理

考生应该如何回答

序列化 是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。Serializable是Java提供的序列化机制,而 Parcelable则是Android提供的适合于内存中进行传输的序列化方式。

Serializable

Serializable是Java中提供的一个 序列化接口,然而这个接口并没有任何方法需要实现者实现。

public interface Serializable {
    
    
}

这表示Serializable接口知识用来标识当前类可以被序列化与反序列化。

基本使用

实现了Serializable接口的类对象能够通过 ObjectOutputStream 将需要序列化数据写入到流中,因为 Java IO 是一种装饰者模式,因此可以通过 ObjectOutStream 包装 FileOutStream 将数据写入到文件中或者包装 ByteArrayOutStream 将数据写入到内存中。也可以通过 ObjectInputStream 从磁盘或者内存读取数据然后转化为指定的对象即可(反序列化)。

try {
    
    
	TestBean serialization = new TestBean("a","b");
    //序列化
	ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("/path/xxx"));
	os.writeObject(serialization);
	//反序列化
	ObjectInputStream is = new ObjectInputStream(new FileInputStream("/path/xxx"));
	TestBean deserialization = (TestBean) is.readObject();
} catch (IOException e) {
    
    
	e.printStackTrace();
}

实现了Serializable接口的类中成员属性除基本数据类型外,即引用类型,也需要实现Serializable接口,否则将在序列化时抛出java.io.NotSerializableException 异常。

public class TestBean implements Serializable {
    
    

    private String name;
    private String pwd;
    //Gson未实现Serializable接口,TestBean实例对象在序列化时抛出NotSerializableException
    private Gson gson = new Gson();
    public TestBean(String name, String pwd) {
    
    
        this.name = name;
        this.pwd = pwd;
    }

    public TestBean() {
    
    
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getPwd() {
    
    
        return pwd;
    }

    public void setPwd(String pwd) {
    
    
        this.pwd = pwd;
    }

}

因此,如果需要对某个类进行序列化时,对于类中不需要进行序列化与反序列化的属性,可以使用 transient 关键字声明。

private transient Gson gson = new Gson();
serialVersionUID

在实现了Serializable接口的类中,应该为此类定义一个serialVersionUID属性:

扫描二维码关注公众号,回复: 15527083 查看本文章
private static final long serialVersionUID = 1L; 

虽然不定义程序依然能够正常运行。 但是Java序列化的机制是通过判断类的serialVersionUID来验证的版本一致的。

序列化操作时会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会自动检测文件中的serialVersionUID,判断它是否与当前类中的serialVersionUID一致。如果一致说明序列化文件的版本与当前类的版本是一样的,可以反序列化成功,否则就失败。

例如在A程序中TestBean类的serialVersionUID=1L,而在程序B中TestBean类的serialVersionUID=2L。 那么A程序序列化输出的数据,在B程序中就无法反序列化为TestBean对象。

Parcelable

Parcelable是Android为我们提供的序列化的接口。相对于Java的Serializable,Parcelable的使用稍显复杂:

public class TestBean implements Parcelable {
    
    

    private String name;
    private String pwd;
    
    public TestBean(String name, String pwd) {
    
    
        this.name = name;
        this.pwd = pwd;
    }

    public TestBean() {
    
    
    }

    public int describeContents() {
    
    
    	return 0;
    }
    //序列化
	public void writeToParcel(Parcel out, int flags) {
    
    
		out.writeString(name);
         out.writeString(pwd);
	}
    public static final Parcelable.Creator<TestBean> CREATOR 
        = new Parcelable.Creator<TestBean>(){
    
    
        	public TestBean createFromParcel(Parcel in) {
    
    
				return new TestBean(in);
			}

			public MyParcelable[] newArray(int size) {
    
    
				return new TestBean[size];
			}
    }
    private TestBean(Parcel in) {
    
    
        // 反序列化:按序列化顺序读取
		name = in.readString();
		pwd = in.readString();
    }
}

Parcelable接口的实现类是通过Parcel写入和恢复数据的,并且必须要有一个非空的静态变量 CREATOR。

Parcel

Parcel其实就是一个数据载体,可以将序列化之后的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读出字节流,并反序列化成对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mbJWICkG-1686553360030)(images\parcel.png)]

Parcel可以读写原始数据类型,也可以读写实现了Parcelable对象。

因此Parcelable实现序列化的原理就是将一个完整的对象进行分解,而分解后的每一部分都是基本数据类型或者其他实现了Parcelable/Serializable的类型,从而实现传递对象的功能。

区别

Parcelable和Serializable都是实现序列化并且在Android中都可以使用Intent进行数据传递。Serializable是Java的实现方式,实现过程中会频繁的IO操作,但是实现方式简单。而Parcelable是Android提供的方式,效率比较高(号称比Serializable快10倍),但是实现起来复杂一些 。

如果只需要在内存中进行数据传输是,序列化应该选择Parcelable,而如果需要存储到设备或者网络传输上应该选择Serializable。这是因为Android不同版本Parcelable数据规则可能不同,所以不推荐使用Parcelable进行数据持久化。

更多面试题详解可以扫描二维码免费领取!

猜你喜欢

转载自blog.csdn.net/Misdirection_XG/article/details/131169063