序列化-Serializable和Parcelable

Serializable

在Android开发中,Serializable是一种用于将对象序列化和反序列化的接口。它是Java的标准序列化方式,可以在任何Java平台上使用。

下面是使用Serializable进行对象序列化的步骤:

  1. 在要序列化的类中实现Serializable接口:在类定义上实现Serializable接口。
import java.io.Serializable;public class MyObject implements Serializable {private int id;private String name;// 构造函数public MyObject(int id, String name) {this.id = id;this.name = name;}// 省略get和set
}
  1. 序列化对象:创建一个输出流,并将对象写入该输出流。
MyObject myObject = new MyObject(1, "Example");try {FileOutputStream fileOut = new FileOutputStream("path/to/file");ObjectOutputStream out = new ObjectOutputStream(fileOut);out.writeObject(myObject);out.close();fileOut.close();
} catch (IOException e) {e.printStackTrace();
}
  1. 反序列化对象:创建一个输入流,并从输入流中读取对象。
MyObject myObject = null;try {FileInputStream fileIn = new FileInputStream("path/to/file");ObjectInputStream in = new ObjectInputStream(fileIn);myObject = (MyObject) in.readObject();in.close();fileIn.close();
} catch (IOException | ClassNotFoundException e) {e.printStackTrace();
}

通过实现Serializable接口,你可以使用Java的标准序列化机制对对象进行序列化和反序列化。但需要注意的是,尽管Serializable是方便的,但它的序列化过程相对较慢,并且会消耗大量的内存。因此,在Android开发中,如果性能要求较高,建议使用Parcelable接口进行对象序列化。

原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同时才能够正常的被反序列化。serialVersionUID的详细工作机制是这样的:序列化的时候系统会把当前类的serialVersionUID写入序列化的文件中(也可能是其他的中介),当反序列化的时候系统会去检测文件中的serialVersionUID,看它是否和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化,否则就说明当前类和序列化的类相比发生了某些变换

给serialVersionUID制定为1L或者采用Eclipse根据当前类结构去生成的hash值,这两者并没有本质区别。

  • 静态成员变量属于类不属于对象,所以不会参与序列化过程
  • 其次用transient关键字标记的成员变量不参与序列化过程

Parcelable接口

在Android开发中,Parcelable是一种用于将对象序列化和反序列化的接口。它比Java中的Serializable更高效,因为它是在内存中直接操作对象的字段,而不会经过IO流的序列化和反序列化过程。

下面是使用Parcelable进行对象序列化的步骤:

  1. 实现Parcelable接口:在要序列化的类中实现Parcelable接口,并实现其中的方法。Parcelable接口包括两个核心方法:writeToParcel()createFromParcel()writeToParcel()方法用于将对象的字段写入Parcel对象,createFromParcel()方法用于从Parcel对象中读取字段并创建对象。
public class MyObject implements Parcelable {private int id;private String name;// 构造函数public MyObject(int id, String name) {this.id = id;this.name = name;}protected MyObject(Parcel in) {id = in.readInt();name = in.readString();}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeInt(id);dest.writeString(name);}@Overridepublic int describeContents() {return 0;}public static final Creator<MyObject> CREATOR = new Creator<MyObject>() {@Overridepublic MyObject createFromParcel(Parcel in) {return new MyObject(in);}@Overridepublic MyObject[] newArray(int size) {return new MyObject[size];}};
}
  • 序列化对象:将对象序列化为Parcel对象。
MyObject myObject = new MyObject(1, "Example");
Parcel parcel = Parcel.obtain();
myObject.writeToParcel(parcel, 0);
  • 反序列化对象:从Parcel对象中读取字段并创建对象。
parcel.setDataPosition(0);
MyObject myObject = MyObject.CREATOR.createFromParcel(parcel);

这样,你就可以使用Parcelable接口来实现Android中的对象序列化和反序列化了。注意,要确保对象的字段顺序一致,以便正确地读取和写入Parcel对象。另外,Parcelable只适用于Android平台,如果需要在不同平台之间进行对象序列化,考虑使用其他的序列化方式,如JSON(有很便捷的api进行读入读出)

Parcelable的方法说明:

方法功能标记位
createFromParcel(Parcel in)从序列化的对象中创建原始对象
newArray[int size]创建指定长度的原始对象数组
User(Parcel in)从序列化的对象中创建原始对象
write ToParcel(Parcel out, int flags)将当前对象写入序列化结构中,其中flags标识有两种值0或1(参见右侧标记位)。为1时标识当前对象需要作为返回值返回,不能立即释放资源,几乎所有情况都为0PARCELABLE_WRITE_RETURN_VALUE
describeContents返回当前对象的内容描述。如果含有文件描述符,返回1(参见右侧标记位),否则返回0,几乎所有的情况都返回0CONTENTS_FILE_DESCRIPTOR
  • 系统已经为我们提供了许多实现了Parcelable接口的类,它们都是可以直接序列化的,比如Intent、Bundle、Bitmap等,同时List和Map也可以序列化,前提是它们里面的每个元素都是可序列化的。

如何选取

Serializable是Java中的序列化接口,其使用起来简单但是开销很大,序列化和反序列化需要大量I/O操作。而Parceleble是Android中的序列化方式,因此更适合在Android平台上,缺点是麻烦,但是效率高,这是Android推荐的序列化方式,所以我们要首选Parcelable。Parcelable主要用在内存序列化上,通过Parcelable将对象序列化到存储设备中或者将对象序列化之后通过网络传输,但是过程稍显复杂,因此在这两种情况下建议大家使用Serializable。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/186340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

珠宝模具3d仿真沉浸式交互展示更易分享传播

3D云展会经过近几年的蓬勃发展&#xff0c;迅速受到参展企业和客户的多方认可和支持&#xff0c;那么随着市场再度恢复&#xff0c;各种展会络绎不绝&#xff0c;想要快速打造一个逼真的线上3D云展会成为企业刚需。3D云展会线上搭建平台是web3d开发公司深圳华锐视点根据领先的三…

GESP编程冲刺第一天

题目描述&#xff1a; 1. 画三角形 【问题描述】 输入一个正整数 n&#xff0c;请使用大写字母拼成一个这样的三角形图案&#xff08;参考样例 输入输出&#xff09;&#xff1a;三角形图案的第 1 行有 1 个字母&#xff0c;第 2 行有 2 个字母&#xff0c;以此类推&#xf…

OPC UA使用opc.uafx.advanced开发客户端、服务端

OPC在自动化行业使用很广泛&#xff0c;好一点的PLC支持OPC协议&#xff0c;比如国内的汇川、禾川PLC对应高端的PLC都支持OPC UA协议&#xff0c;低端一点的则使用Modbus和上位机通讯&#xff0c;或者TCP自定义格式。相比于modbus协议&#xff0c;OPC不用确定寄存器地址&#x…

CSS 在性能优化方面的实践

前言 CSS&#xff08;层叠样式表&#xff09;是一种用于描述网页外观和格式的语言。随着网页变得越来越复杂&#xff0c;CSS文件的大小也随之增加&#xff0c;这可能会对网页性能产生负面 .box {width: 100px;height: 100px;transition: transform 0.3s; }.box:hover {transf…

全网最最全的Jmeter接口测试:jmeter_逻辑控制器_交替控制器Jmeter(22):jmeter_逻辑控制器_交替控制器

交替控制器 该控制器包含的取样器步骤在每次循环中交替执行 交替控制器指每次运行一次时在交替控制器下的采样器只执行一个&#xff1b;如下图&#xff1a; 忽略子控制模块&#xff1a;如果勾选此项,交替控制器将子控制器像单一请求元素一样&#xff0c;一次 只允许一个请求/…

Java中的JMX的使用

文章目录 1. 定义和存在的意义2. 架构2.1 Instrumentation2.2 JMX Agent2.3 Remote Management 3. 启动和连接3.1 注册MBean3.2 有两个方式启动JMX Agent3.3 Remote Management(客户端) 4. MBeanServerConnection使用4.1 列出所有的MBean4.2 列出所有的Domain4.3 MBean计数4.4 …

算法:Java计算二叉树从根节点到叶子结点的最大路径和

要求从根节点到叶子结点的最大路径和&#xff0c;可以通过递归遍历二叉树来实现。对于二叉树中的每个节点&#xff0c;我们都可以考虑包含该节点的最大路径和。在递归的过程中&#xff0c;我们需要不断更新全局最大路径和。 具体的思路 递归函数设计&#xff1a; 设计一个递归函…

常用的设计模式

常用的设计模式&#xff1a; 一、单例模式 java中单例模式是一种常见的设计模式&#xff0c;单例模式的写法有好几种&#xff0c;这里主要介绍三种&#xff1a;懒汉式单例、饿汉式单例、双重检查锁定 1、单例模式有以下特点&#xff1a;   a、单例类只能有一个实例。   b…

36.JavaScript补完计划:typescript

点赞收藏加关注&#xff0c;你也能住大别墅&#xff01; 一、什么是typescript 二、应用场景 我认为JavaScript的特点就是在于它强大的延展性&#xff0c;不仅蔓延到了后端&#xff0c;而且也逐渐成为代码世界无法被忽视的存在。那么&#xff0c;编写js代码时我们都会经常遇到…

uniapp项目打包h5,支持文件协议,使用vconsole调试移动端

uniapp项目需要打包h5&#xff0c;并且需要嵌套到一个原生的移动端项目中&#xff0c;需要支持文件协议能直接访问 打包设置 设置./基础路径 引入vconsole调试移动端 <script src"https://unpkg.com/vconsole/dist/vconsole.min.js"></script>可以将…

高效开发之:判断复杂list中的对象属性是否包含某个值

技术使用&#xff1a;使用了Java 8引入的Stream API以及Optional类。这些特性用于简化集合的处理和减少空指针异常。 List<ResourceInfoDto> authData chatBase.getData();String baseName dto.getBaseName();Optional<ResourceInfoDto> authWithResourceCode a…

【Android Jetpack】Lifecycle 感知生命周期

文章目录 背景示例LifeCycle的原理LifecycleOwner自定义LifecycleOwnerLifecycleObserver 示例改进使用LifecycleService解耦Service与组件整个应用进程的生命周期ProcessLifecycleOwner 背景 在Android应用程序开发中&#xff0c;解耦很大程度上表现为系统组件的生命周期与普…

[跑代码]BK-SDM: A Lightweight, Fast, and Cheap Version of Stable Diffusion

Installation(下载代码-装环境) conda create -n bk-sdm python3.8 conda activate bk-sdm git clone https://github.com/Nota-NetsPresso/BK-SDM.git cd BK-SDM pip install -r requirements.txt Note on the torch versions weve used torch 1.13.1 for MS-COCO evaluation…

9.vue3项目(九):spu管理页面的新增和修改

目录 一、SPU和SKU概念 二、SPU静态搭建 1.代码编辑 2.效果展示 三、封装接口以及出参入参

windows远程桌面登录,提示:“出现身份验证错误,要求的函数不受支持”

问题&#xff1a; windows登录远程桌面&#xff0c;提示&#xff1a;“出现身份验证错误&#xff0c;要求的函数不受支持”&#xff0c;如下图&#xff1a; 问题原因&#xff1a; windows系统更新&#xff0c;微软系统补丁的更新将 CredSSP 身份验证协议的默认设置进行了调…

Windows + docker + python + vscode : 使用容器docker搭建python开发环境,无需本地安装python开发组件

下载docker for Windows docker window下载 如果没有翻墙工具&#xff0c;可以该网盘中的docker 链接&#xff1a;https://pan.baidu.com/s/11zLy3e5kusZR-4m_Fq_cqg?pwdesmv 提取码&#xff1a;esmv 安装docker docker的安装会重启电脑&#xff0c;不要惊讶&#xff0c;且…

linux中 struct page 与物理地址的关系

由struct page 找到对应物理地址 以sparse模型为例&#xff0c;每个numa node 有自己的物理地址。在初始化时&#xff08;sparse_init_nid&#xff09;会将可用内存按section&#xff08;比例32k个页&#xff09;大小分成若干section&#xff0c;在大于dma区的内存中为他分配一…

Unity 注释的方法

1、单行注释&#xff1a;使用双斜线&#xff08;//&#xff09;开始注释&#xff0c;后面跟注释内容。通常注释一个属性或者方法&#xff0c;如&#xff1a; //速度 public float Speed;//打印输出 private void DoSomething() {Debug.Log("运行了我"); } …

构建智能预约体验:深度解析预约系统源码的代码精髓

随着数字化时代的发展&#xff0c;预约系统在各行业中扮演着越来越重要的角色。本文将深入研究预约系统源码&#xff0c;通过代码示例分析其技术要点&#xff0c;为开发者提供实用的指导&#xff0c;助力构建智能、高效的预约体验。 技术栈综述 预约系统源码采用了现代化的技…

JAVEE初阶 多线程基础(四)

线程安全 一.线程安全存在的问题二.锁三.关于锁的理解四.关于锁操作混淆的理解4.1两个线程是否对同一对象加锁 一.线程安全存在的问题 为什么这里的count不是一百万呢?这就是线程所存在的不安全的问题,由于线程是抢占式执行,同时执行count,操作本质是三个指令 1.load 读取内存…