一、知识预备

根据使用Serializable的使用场景,可以发现所涉及的场景都是跨进程的,就是要做的事情不是在一个java进程中完成的,我们都知道java进程是基于jvm跑起来的,而每一个被创建出来的对象都是放在堆里面的,如对象实例中的属性值,但是跨进程时每个Java进程都有一个jvm,也就是各自jvm中都有一个堆用来存放对象信息(很多博客上讲的是对象存放于内存之中,简直云里雾里,新人根本搞不清楚,一定要讲到java的根本jvm)。这时候问题引入,我们如何将A进程的Student实例,传输给本机B进程呢?又或者说如何传输给另外一台机器上的C进程呢?

二、引入序列化

我们为什么需要序列化呢?或者说什么情况下需要用到序列化呢?或者说如果没有序列化的话,哪些场景是我们处理不了的呢?
第一种情况是:一般情况下Java对象的声明周期都比Java虚拟机的要短,实际应用中我们希望在JVM停止运行之后能够持久化指定的对象,这时候就需要把对象进行序列化之后保存。
也就是说,在Java进程启动后,new出来放到内存中的对象(JVM中的堆空间),当JVM停止之后内存空间就被释放掉了,刚才创造的java进程中的世界都消失了,再次启动又会重新创建出来一个新的空间。
那么如果说是一个单机游戏进程,比如说单机版梦幻西游,人物初始属性中的攻击、防御、魔法都是0,你练了几级之后,这几个属性就会增加,那么今天你玩够了,把游戏进程给关了,那么你刚刚创建的游戏人物的相关信息都要保存下来的(很多游戏里面,在你退出的时候会提示你让你存档,就是这个意思),下次再打开游戏的时候就是将你刚才存档的信息读入到内存,在游戏界面再次的显示出来。

三、过程解析

Java序列化是指把Java对象保存为二进制字节码的过程,Java反序列化是指把二进制码重新转换成Java对象的过程。
当然这句话也让人云里雾里,因为对象就是类的实例对象生成之后就是在内存中,这句话应该这样表达,Java序列化是指把位于堆空间的Java对象以二进制字节码的形式保存为文件,反序列化就是将文件中的二进制字节码读取解析到内存中重新转化为Java对象的过程。
举个例子
package test;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class SerializableTest {public static void main(String[] args) throws IOException, ClassNotFoundException {FileOutputStream fos = new FileOutputStream("game-person.info");ObjectOutputStream oos = new ObjectOutputStream(fos);GamePerson personIn = new GamePerson();personIn.setName("abcde");personIn.setLevel(1);personIn.setForceValue(2);personIn.setDefenseValue(3);oos.writeObject(personIn);oos.flush();oos.close();FileInputStream fis = new FileInputStream("game-person.info");ObjectInputStream ois = new ObjectInputStream(fis);GamePerson personOut = (GamePerson) ois.readObject();System.out.println(personOut.getName());System.out.println(personOut.getLevel());System.out.println(personOut.getForceValue());System.out.println(personOut.getDefenseValue());}
}class GamePerson implements Serializable {private static final long serialVersionUID = 1L;private String name;private int level;private int forceValue;private int defenseValue;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getLevel() {return level;}public void setLevel(int level) {this.level = level;}public int getForceValue() {return forceValue;}public void setForceValue(int forceValue) {this.forceValue = forceValue;}public int getDefenseValue() {return defenseValue;}public void setDefenseValue(int defenseValue) {this.defenseValue = defenseValue;}}

运行之后,在workspce目录下会生成game-person.info二进制文件,我们打开看看

四、修改序列化后的文件

重点来了,现在人物属性由内存持久化到了本地,那么我们是不是可以做一些手脚?
嘿嘿,我们把十六进制中各个属性尝试改一下,999(十进制) = 3E7(十六进制),我们改序列化后的文件见下图。
然后在从文件读取看看看
public class SerializableTest {public static void main(String[] args) throws IOException, ClassNotFoundException {FileInputStream fis = new FileInputStream("game-person.info");ObjectInputStream ois = new ObjectInputStream(fis);GamePerson personOut = (GamePerson) ois.readObject();System.out.println(personOut.getName());System.out.println(personOut.getLevel());System.out.println(personOut.getForceValue());System.out.println(personOut.getDefenseValue());}
}

  一刀999,惊不惊喜,意不意外!

五、总结

  除了本地--内存,这种序列化的应用场景外。另外一种也就是第二种情况是:需要把Java对象通过网络进行传输的时候。因为数据只能够以二进制的形式在网络中进行传输,因此当把对象通过网络发送出去之前需要先序列化成二进制数据,在接收端读到二进制数据之后反序列化成Java对象。

关于Serializable的一个形象的例子相关推荐

  1. 关于CDN原理的一个形象例子

    最近想了解下CDN,从网上找了一些文档看了下,有的配合dig命令解释得蛮复杂的,但总感觉缺乏一些形象的例子供初学者掌握.首先,有几个概念需明确: 1.GSLB全局负载均衡和iDNS智能DNS是一个意思 ...

  2. .net中的对象序列化(1): 序列化是什么, 以及一个简单的例子

    1. 为什么需要序列化,什么是序列化 对于一个程序来说, 使用到的对象都是存在于内存中的.如果想保存这些对象的运行时状态, 或者需要在不同进程或者网络间传递对象,就需要序列化. 序列化就是讲运行中的对 ...

  3. JPA基础(二)之实现一个简单 JPA 例子

    实现一个简单 JAP 例子 需要学习 JPA,首先需要把环境搭起来,这里选择实现 JPA 规范的持久层框架是 Hibernate,版本为 5.0.7.Final,并且采用 maven 进行依赖包的管理 ...

  4. 一个生动的例子让你理解Linux的Shell外壳

    目录 0.观前提醒 1.外壳程序 2.命令行解释器 3.生动形象的例子(无敌爆炸好笑) 4.稍作总结 0.观前提醒 (1)建议可以直接先看 3.生动形象的例子(直接点目录跳转) , 再回来看前面的理论 ...

  5. 一个简单的例子学会github repository的webhook

    2019独角兽企业重金招聘Python工程师标准>>> github的webhook是个有用的功能,允许开发人员指定一个服务器的url.当开发者对github仓库施加操作,比如提交代 ...

  6. 一个具体的例子学习Java volatile关键字

    相信大多数Java程序员都学习过volatile这个关键字的用法.百度百科上对volatile的定义: volatile是一个类型修饰符(type specifier),被设计用来修饰被不同线程访问和 ...

  7. 一个简单的例子看java线程机制

    一个简单的例子看java线程机制 作者: zyf0808 发表日期: 2006-03-26 11:20 文章属性: 原创 复制链接 import java.util.*; public class T ...

  8. Cassandra使用 —— 一个气象站的例子

    使用场景: Cassandra非常适合存储时序类型的数据,本文我们使用一个气象站的例子(该气象站每分钟需要存储一条温度数据). 一.方案1:每个设备占用一行 这个方案的思路就是给每个数据源创建一行,比 ...

  9. blockchain 区块链200行代码:在JavaScript实现的一个简单的例子

    blockchain 区块链200行代码:在JavaScript实现的一个简单的例子 了解blockchain的概念很简单(区块链,交易链块):它是分布式的(即不是放置在同一台机器上,不同的网络设备上 ...

最新文章

  1. JS中的作用域(一)-详谈
  2. 有计划地开放数据 促进大数据法规落地
  3. linux下编辑某个文件,linux下修改以某个字母开头的文件后戳
  4. 人口普查系统_晋江市召开第七次人口普查区域划分及标绘系统操作培训会
  5. 再见收费的Navicat!操作所有数据库靠它就够了!
  6. svn如何取消某个文件的版本管理_微服务架构如何统一管理工程配置文件
  7. 数据仓库建模与ETL实践技巧
  8. 阿尔伯塔大学计算机科学本科几年,本科——21阿尔伯塔大学CS专业早录取
  9. 2021-2025年中国再加工医疗器械行业市场供需与战略研究报告
  10. java类库支持_第十二章:开发支持类库
  11. 网络工程专业大学生,需要考HICE吗?
  12. 调用百度api 生成短网址
  13. pip install XXX总是报错,例如:Exception: Traceback (most recent call last):这种错误怎么办?
  14. c语言火柴棒编辑,【NOIP2008】火柴棒等式
  15. 黑客帝国、乱雨纷飞效果
  16. mysql2005编辑器用法,文本编辑器 - Visual Studio的隐藏功能(2005-2010)?
  17. python socks代理 命令行_Python使用socks代理
  18. linux系统安装telnet服务
  19. c语言计算特殊角的正弦值,特殊角的三角函数值表 常用的正余弦函数值
  20. sumatrapdf关闭当前tab快捷键

热门文章

  1. 模建Bentley.STAAD.Pro.Connect.Edition.v21.00.00.57.build.08072017
  2. 【putty】html中调起客户端putty
  3. 论文阅读:TensorMask: A Foundation for Dense Object Segmentation
  4. 黑客攻击-木马免杀之PE文件
  5. 信用卡知识:自动扣款日不等于最后还款日_刷卡技巧_财经_腾讯网
  6. 小程序12306服务器,12306 网站、官方 app 外,小程序也了上线高铁订餐功能
  7. google cash中文版
  8. GNSS模块的PPS和ToD
  9. uipath字符串操作
  10. 2021华为杯数学建模B题“空气质量预报二次建模” 预处理思路+Python代码