Java 序列化Serializable详解(附详细例子)

Java 序列化Serializable详解(附详细例子)

1、什么是序列化和反序列化
Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。

 

2、什么情况下需要序列化 
a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;

3、如何实现序列化

将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化。

 

4、序列化和反序列化例子

如果我们想要序列化一个对象,首先要创建某些OutputStream(如FileOutputStream、ByteArrayOutputStream等),然后将这些OutputStream封装在一个ObjectOutputStream中。这时候,只需要调用writeObject()方法就可以将对象序列化,并将其发送给OutputStream记住:对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构。而反序列的过程(即将一个序列还原成为一个对象),需要将一个InputStream(如FileInputstream、ByteArrayInputStream等)封装在ObjectInputStream内,然后调用readObject()即可。

 

package com.sheepmu;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class MyTest implements Serializable
{private static final long serialVersionUID = 1L;private String name="SheepMu";private int age=24;public static void main(String[] args){//以下代码实现序列化try {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));//输出流保存的文件名为 my.out ;ObjectOutputStream能把Object输出成Byte流MyTest myTest=new MyTest();oos.writeObject(myTest); oos.flush();  //缓冲流 oos.close(); //关闭流} catch (FileNotFoundException e) {		 e.printStackTrace();} catch (IOException e) {e.printStackTrace();} fan();//调用下面的  反序列化  代码}public static void fan()//反序列的过程{	 ObjectInputStream oin = null;//局部变量必须要初始化try{oin = new ObjectInputStream(new FileInputStream("my.out"));} catch (FileNotFoundException e1){		 e1.printStackTrace();} catch (IOException e1){e1.printStackTrace();}      MyTest mts = null;try {mts = (MyTest ) oin.readObject();//由Object对象向下转型为MyTest对象} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}     System.out.println("name="+mts.name);    System.out.println("age="+mts.age);    }
}

会在此项目的工作空间生成一个 my.out文件。序列化后的内容稍后补齐,先看反序列化后输出如下:

 

name=SheepMu
age=24

5、序列化ID

序列化 ID 在 Eclipse 下提供了两种生成策略,一个是固定的 1L,一个是随机生成一个不重复的 long 类型数据(实际上是使用 JDK 工具生成),在这里有一个建议,如果没有特殊需求,就是用默认的 1L 就可以,这样可以确保代码一致时反序列化成功。这也可能是造成序列化和反序列化失败的原因,因为不同的序列化id之间不能进行序列化和反序列化。

 

6.序列化前和序列化后的对象的关系

是 "=="还是equal? or 是浅复制还是深复制? 

答案:深复制,反序列化还原后的对象地址与原来的的地址不同

序列化前后对象的地址不同了,但是内容是一样的,而且对象中包含的引用也相同。换句话说,通过序列化操作,我们可以实现对任何可Serializable对象的”深度复制(deep copy)"——这意味着我们复制的是整个对象网,而不仅仅是基本对象及其引用。对于同一流的对象,他们的地址是相同,说明他们是同一个对象,但是与其他流的对象地址却不相同。也就说,只要将对象序列化到单一流中,就可以恢复出与我们写出时一样的对象网,而且只要在同一流中,对象都是同一个。

 

7.静态变量能否序列化

若把上面的代码中的 age变量前加上 static ,输出任然是

name=SheepMu
age=24

但是看下面的例子:

 

package com.sheepmu;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class MyTest implements Serializable
{private static final long serialVersionUID = 1L;private String name="SheepMu";private static int age=24;public static void main(String[] args){//以下代码实现序列化try {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));//输出流保存的文件名为 my.out ;ObjectOutputStream能把Object输出成Byte流MyTest myTest=new MyTest();oos.writeObject(myTest); oos.flush();  //缓冲流 oos.close(); //关闭流} catch (FileNotFoundException e) {		 e.printStackTrace();} catch (IOException e) {e.printStackTrace();} fan();//调用下面的  反序列化  代码}public static void fan(){new MyTest().name="SheepMu_1";//!!!!!!!!!!!!!!!!重点看这两行 更改部分age=1;//!!!!!!!!!!!!!!!!!!!重点看这两行 更改部分ObjectInputStream oin = null;//局部变量必须要初始化try{oin = new ObjectInputStream(new FileInputStream("my.out"));} catch (FileNotFoundException e1){		 e1.printStackTrace();} catch (IOException e1){e1.printStackTrace();}      MyTest mts = null;try {mts = (MyTest ) oin.readObject();//由Object对象向下转型为MyTest对象} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}     System.out.println("name="+mts.name);    System.out.println("age="+mts.age);    }
}

输出结果为:

 

name=SheepMu
age=1
为何把最上面代码的age变量添上static 后还是反序列化出了24呢?而新的从新对变量赋值的代码,不是static的得到了序列化本身的值,而static的则得到的是从新附的值。原因: 序列化会忽略静态变量,即序列化不保存静态变量的状态。静态成员属于类级别的,所以不能序列化。即 序列化的是对象的状态不是类的状态。这里的不能序列化的意思,是序列化信息中不包含这个静态成员域。最上面添加了static后之所以还是输出24是因为该值是JVM加载该类时分配的值。注:transient后的变量也不能序列化,但是情况稍复杂,稍后开篇说。

8、总结:

a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;

b)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

c) static,transient后的变量不能被序列化;

转载于:https://www.cnblogs.com/cx6872/p/6049839.html

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

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

相关文章

kettle-实现每个分组的前N的数据

2019独角兽企业重金招聘Python工程师标准>>> 第一步:创建表及数据: create table uid(uid int, --uidcate varchar(20), --类别price double --金额 ) insert into uid values(123,c1,21); insert into uid values(123,c2,23); insert into u…

重写__repr__与__str__函数

重写:将函数重新定义写一遍__str__():再调用print 打印对象时自动调用,是给用户用的是一个描述对象的方法__repr__():是给机器用的,在python解释器里面直接敲对象名再回车调用的方法注意:在没有str时,且有repr,str re…

linux nexus 使用问题

2019独角兽企业重金招聘Python工程师标准>>> 问题一,启动提示设置RUN_AS_USERroot 但是,设置export或 /etc/profile未生效。 **************************************** WARNING - NOT RECOMMENDED TO RUN AS ROOT *************************…

项目回顾-PopupWindow

右上菜单,可以通过 重写 onCreateOptionsMenu指定 menu, 重写 onOptionsItemSelected 来响应点击事件 不过 这个菜单在某些手机上弹出的有点卡顿,而且如果不对主题进行设置,会从actionbar 上直接弹出,而不是下面 如果想…

android listpreference 自定义,Android ListPreference的用法一

xmlns:android"http://schemas.android.com/apk/res/android"android:key"screen_list"android:title"标题"android:summary"说明摘要">< ListPreferenceandroid:key"myListPreference"android:title"标题"…

C语言求最大公约数和最小公倍数的几种算法

求最小公倍数算法&#xff1a; 最小公倍数两整数的乘积最大公约数 求最大公约数算法&#xff1a; (1)辗转相除法 有两整数a和b&#xff1a; ① a%b得余数c ② 若c0&#xff0c;则b即为两数的最大公约数 ③ 若c≠0&#xff0c;则ab&#xff0c;bc&#xff0c;再回去执行①…

3月15日云栖精选夜读:双管齐下,MaxCompute数据上云与生态

双管齐下&#xff0c;MaxCompute数据上云与生态 作者&#xff1a;场景研读 Go语言并发机制初探 作者&#xff1a;邴越 趣拍云短视频SDK全面升级&#xff0c;简单易用引开发者点赞 作者&#xff1a;sherry是雪梨 发表在&#xff1a;趣拍云团队 阿里云机器学习平台编程模型演…

qt android glsl,基于Qt的OpenGL学习(1)—— Hello Triangle

简介要学习OpenGL的话&#xff0c;强烈安利这个教程JoeyDeVries的learnopengl&#xff0c;这里是中文翻译好的版本。教程中使用OpenGL是通过GLFW这个库&#xff0c;而在Qt中对OpenGL封装得很好&#xff0c;并且和GUI以及IO相关的处理Qt更便捷&#xff0c;学习起来更轻松。这里就…

解决:Not Found: /favicon.ico

直接说解决办法&#xff1a; &#xff08;1&#xff09;制作一个 favicon.ico图标放在<head></head>标签中 <link rel"shortcut icon" href"xxxxxxxxxx.ico" type"image/x-icon" /> <!--制作的图标&#xff0c;使用hr…

多态方法调用的解析和分派

方法调用并不等同于方法执行&#xff0c;方法调用阶段唯一的任务就是确定被调用方法的版本&#xff08;即调用哪一个方法&#xff09;&#xff0c;暂时还不涉及方法内部的具体运行过程。在程序运行时&#xff0c;进行方法调用是最普遍、最频繁的操作&#xff0c;Class文件的编译…

ES6:Set和Map

Set Set:类似数组&#xff0c;但是成员的值都是唯一的&#xff0c;没有重复。Set本身是一个构造函数&#xff0c;用来生成Set数据结构。他包含的方法&#xff1a;add: 添加某个值&#xff0c;返回Set结构本身。delete: 删除某个值&#xff0c;返回一个布尔值&#xff0c;表示是…

九九乘法表[循环嵌套]

#九九乘法表 # 1*11 # 1*22 2*24 # 1*33 2*36 3*39 # ...#循环嵌套 #行数 i 1 while i < 9:# 打印每行的内容j 1while j < i:print("%d * %d %3d " % (i, j, i * j), end)j 1print() # 换行i 1while嵌套&#xff1a;w 1 while w < 10: #外层循…

关于用VS写C程序运行时出现烫字以及乱码的问题的原因

最近在复习C语言写程序时&#xff0c;突然碰到标题上的这种情况&#xff0c;后来经过上网查找以及逐步调试才发现原来是在打印数组的时候“越界”导致的&#xff0c;因为程序在默认初始化char类型的数组时&#xff0c;初始化的值是“烫”字&#xff0c;一般情况下是字符串未初始…

javascript函数调用的各种方法!!

在JavaScript中一共有下面4种调用方式&#xff1a; (1) 基本函数调用 (2)方法调用 (3)构造器调用 (4)通过call()和apply()进行调用 1. 基本函数调用 普通函数调用模式&#xff0c;如&#xff1a; JavaScript code?1234function fn(o){…… }fn({x:1});在基本函数调用中&#x…

ARM TK1 安装kinect驱动

首先安装usb库 $ git clone https://github.com/libusb/libusb.git 编译libusb需要的工具 $ sudo apt-get install autoconf autogen $ sudo apt-get install libtool $ sudo apt-get install libudev* 编译安装 $ sudo ./autogen.sh $ sudo make $ sudo make install $ sudo l…

如何在一个html页面中提交两个post,如何在同一个页面上从Django和Ajax获得多个post请求?...

我一整天都在为这事犯愁。似乎什么都没用。这是我的情况。在我有一个Django表单&#xff0c;有两个字段&#xff1a;redirect_from&#xff0c;redirect_to。此表单有两个提交按钮&#xff1a;Validate和{}。当页面加载时&#xff0c;Submit被隐藏&#xff0c;只显示Validate。…

大数据入门:各种大数据技术的介绍

大数据我们都知道hadoop&#xff0c;可是还会各种各样的技术进入我们的视野&#xff1a;Spark&#xff0c;Storm&#xff0c;impala&#xff0c;让我们都反映不过来。为了能够更好的架构大数据项目&#xff0c;这里整理一下&#xff0c;供技术人员&#xff0c;项目经理&#xf…

高可用与负载均衡(5)之基于客户端的负载均衡

什么是客户端负载均衡 基于客户端的负载均衡&#xff0c;简单的说就是在客户端程序里面&#xff0c;自己设定一个调度算法&#xff0c;在向服务器发起请求的时候&#xff0c;先执行调度算法计算出向哪台服务器发起请求&#xff0c;然后再发起请求给服务器。 基于客户端负载均衡…

Variant 与 内存泄露

http://blog.chinaunix.net/uid-10386087-id-2959221.html 今天遇到一个内存泄露的问题。是师兄检测出来的。Variant类型在使用后要Clear否则会造成内存泄露&#xff0c;为什么呢&#xff1f; Google一下找到下面一篇文章&#xff0c;主要介绍了Com的内存泄露&#xff0c;中间有…

安装安全类软件进行了android签名漏洞修补,魅族MX3怎么升级固件体验最新比较稳定的版本...

魅族mx3固件怎么升级?flyme os系统会持续更新&#xff0c;升级魅族MX3手机系统需先下载MX3的升级固件&#xff0c;升级固件分为体验版和稳定版。魅族MX3固件有体验版和稳定版两种&#xff0c;顾名思义&#xff0c;体验版为最新版但相比稳定版来说存在更多的漏洞&#xff0c;升…