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()即可。

[java] view plaincopy
  1. package com.sheepmu;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.ObjectInputStream;
  7. import java.io.ObjectOutputStream;
  8. import java.io.Serializable;
  9. public class MyTest implements Serializable
  10. {
  11. private static final long serialVersionUID = 1L;
  12. private String name="SheepMu";
  13. private int age=24;
  14. public static void main(String[] args)
  15. {//以下代码实现序列化
  16. try
  17. {
  18. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));//输出流保存的文件名为 my.out ;ObjectOutputStream能把Object输出成Byte流
  19. MyTest myTest=new MyTest();
  20. oos.writeObject(myTest);
  21. oos.flush();  //缓冲流
  22. oos.close(); //关闭流
  23. } catch (FileNotFoundException e)
  24. {
  25. e.printStackTrace();
  26. } catch (IOException e)
  27. {
  28. e.printStackTrace();
  29. }
  30. fan();//调用下面的  反序列化  代码
  31. }
  32. public static void fan()//反序列的过程
  33. {
  34. ObjectInputStream oin = null;//局部变量必须要初始化
  35. try
  36. {
  37. oin = new ObjectInputStream(new FileInputStream("my.out"));
  38. } catch (FileNotFoundException e1)
  39. {
  40. e1.printStackTrace();
  41. } catch (IOException e1)
  42. {
  43. e1.printStackTrace();
  44. }
  45. MyTest mts = null;
  46. try {
  47. mts = (MyTest ) oin.readObject();//由Object对象向下转型为MyTest对象
  48. } catch (ClassNotFoundException e) {
  49. e.printStackTrace();
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }
  53. System.out.println("name="+mts.name);
  54. System.out.println("age="+mts.age);
  55. }
  56. }

会在此项目的工作空间生成一个 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

但是看下面的例子:

[java] view plaincopy
  1. package com.sheepmu;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.ObjectInputStream;
  7. import java.io.ObjectOutputStream;
  8. import java.io.Serializable;
  9. public class MyTest implements Serializable
  10. {
  11. private static final long serialVersionUID = 1L;
  12. private String name="SheepMu";
  13. private static int age=24;
  14. public static void main(String[] args)
  15. {//以下代码实现序列化
  16. try
  17. {
  18. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));//输出流保存的文件名为 my.out ;ObjectOutputStream能把Object输出成Byte流
  19. MyTest myTest=new MyTest();
  20. oos.writeObject(myTest);
  21. oos.flush();  //缓冲流
  22. oos.close(); //关闭流
  23. } catch (FileNotFoundException e)
  24. {
  25. e.printStackTrace();
  26. } catch (IOException e)
  27. {
  28. e.printStackTrace();
  29. }
  30. fan();//调用下面的  反序列化  代码
  31. }
  32. public static void fan()
  33. {
  34. new MyTest().name="SheepMu_1";     //!!!!!!!!!!!!!!!!重点看这两行 更改部分
  35. age=1;        //!!!!!!!!!!!!!!!!!!!重点看这两行 更改部分
  36. ObjectInputStream oin = null;//局部变量必须要初始化
  37. try
  38. {
  39. oin = new ObjectInputStream(new FileInputStream("my.out"));
  40. } catch (FileNotFoundException e1)
  41. {
  42. e1.printStackTrace();
  43. } catch (IOException e1)
  44. {
  45. e1.printStackTrace();
  46. }
  47. MyTest mts = null;
  48. try {
  49. mts = (MyTest ) oin.readObject();//由Object对象向下转型为MyTest对象
  50. } catch (ClassNotFoundException e) {
  51. e.printStackTrace();
  52. } catch (IOException e) {
  53. e.printStackTrace();
  54. }
  55. System.out.println("name="+mts.name);
  56. System.out.println("age="+mts.age);
  57. }
  58. }

输出结果为:

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

8、总结:

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

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

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

from: http://blog.csdn.net/sheepmu/article/details/27579895

Java 序列化Serializable详解(附详细例子)相关推荐

  1. Java 序列化Serializable详解

    转载 Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserializat ...

  2. Java 动态代理详解 ( 附示例源码,建议收藏)

    动态代理在Java中有着广泛的应用,比如Spring AOP.Hibernate数据查询.测试框架的后端mock.RPC远程调用.Java注解对象获取.日志.用户鉴权.全局性异常处理.性能监控,甚至事 ...

  3. serializable java 规则_Java 序列化Serializable详解(附详细例子)

    1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程. 2.什么情况下需要序 ...

  4. java常用集合类详解(有例子,集合类糊涂的来看!)

    Framework 集合框架是一个统一的架构,用来表示和操作集合. 集合框架主要是由接口,抽象类和实现类构成. 接口:蓝色:实现类:红色 Collection |_____Set(HashSet) | ...

  5. java小程序详解_微信小程序登录Java后台接口(详解,附示例代码)

    首先看一下官方文档 地址:微信小程序官方文档API登录接口 我们先对官方给的时序图进行简单的分析 1.当小程序调用wx.login()时,会获得一个code(临时登录凭证),然后我们需要用wx.req ...

  6. Java基本注解详解(超级详细)

    原文链接: 今日头条 Java注解是一个很重要的知识点,用于对代码进行说明,可以对包.类.接口.字段.方法参数.局部变量等进行注解. 掌握好Java注解有利于学习框架底层实现.@mikechen Ja ...

  7. Java虚拟机结构详解,详细分析其构成

    Java虚拟机 java虚拟机(java virtual machine,JVM),一种能够运行java字节码的虚拟机.作为一种编程语言的虚拟机,实际上不只是专用于Java语言,只要生成的编译文件匹配 ...

  8. java treeview使用详解_TreeView详细用法

    Treeview用于显示按照树形结构进行组织的数据. Treeview控件中一个树形图由节点(TreeNode)和连接线组成.TtreeNode是TTreeview的基本组成单元. 一个树的节点又包含 ...

  9. Serializable详解(1):代码验证Java序列化与反序列化

    说明:本文为Serializable详解(1),最后两段内容在翻译上出现歧义(暂时未翻译),将在后续的Serializable(2)文中补充. 介绍:本文根据JDK英文文档翻译而成,本译文并非完全按照 ...

最新文章

  1. 开机流程与主要开机记录区(MBR)
  2. 删除git仓库中的文件(从所有历史中清除,不留痕迹)【不可恢复】
  3. linux rsync 远程同步
  4. Android 系统(239)---Android PMS的创建过程
  5. Linux进程管理+内存管理:进程切换的TLB处理(ASID-address space ID、PCID-process context ID)
  6. 模拟通信与数字信号区别
  7. python 对一个函数执行速度控制的演示
  8. Linux的history命令
  9. 挖金矿 详解(C++)
  10. footer.php 固定底部,让footer固定在页面(视口)底部
  11. 2017年第八届 蓝桥杯 java B组
  12. 解决windows 2003 无法安装vss2005的问题
  13. 四叶草efi_四叶草启动器Clover EFI bootloader v5.0 r5111最新版
  14. MySQL集群Cluster
  15. 胡波外挂做模具3D装配的方法
  16. 字节跳动面试题后台_JAVA字节跳动面试题分享,一面
  17. 如何制作一首歌的歌词 LRC 歌词制作和绑定
  18. 为什么没有工作经验的程序员很难找工作?
  19. 关于Vue框架Element UI中分页器,当前页的问题
  20. Facebook老员工的十点经验

热门文章

  1. cache 的设计与实现--转载
  2. Hyperledger Fabric 1.4 Kafka集群部署教程
  3. eBay数据科学家李睿:自然语言处理在eBay的技术实践 数据 网络 类别 技术 分类器 阅读1593 近日,在飞马网主办的“FMI人工智能大数据高峰论坛”上,来自eBay的数据科学家李睿
  4. Caffe部署中的几个train-test-solver-prototxt-deploy等说明三
  5. Java8 - 自定义实现体会CompletableFuture的原理
  6. 小工匠聊架构-写给研发工程师的全链路压测
  7. java拆解_深入拆解Java虚拟机视频教程
  8. 在Android中实现监听 返回键,主键,菜单键
  9. go 定义一个结构体并赋初始值_Go中必须谈论的四个迷点
  10. Halcon算子:min_max_gray和gray_histo的区别