2019独角兽企业重金招聘Python工程师标准>>>

我们在程序创建的Java对象都是存在于JVM内存中的,也就是Java对象的生命周期一定不会长于JVM,所以如何以一种持久化的方式保留用户创建的对象呢,这就需要用到对象序列化的知识,将序列化的对象重新还原称为Java对象,即为反序列化。关于Java对象序列化与反序列化,我们需要理解的一点是,序列化只是将Java对象以一种二进制数据流的方式保存到本地文件或其他介质中,它实际上保存的只是实例化对象的一种状态,对于静态成员,是无法序列化保存的。

Java对象要支持序列化,该类必须要具有可序列化的特性,真正提供实现序列化与反序列化方式的ObjectInputStream和ObjectOutputStream类。Java对象序列化的方式可以分为普通方式和定制方式两种,普通方式,借助Serializable接口完成,不需要用户做过多的干涉和修改;定制方式,用户可以使用transient关键字修饰类中某个属性,使该属性屏蔽序列化特性,使用transient关键字屏蔽之后,被transient修饰的字段序列化后取默认值,而非序列化之前的实例化对象值。如果需要序列化该字段,我们可以将transient关键字去掉,也可以在该类中重写readObject和writeObject方法,并在重写方法中继续序列化屏蔽的字段,从而达到反屏蔽的效果。除了使用transient关键字,重写readObject和writeObject方法实现定制序列化的方式,还有一种与Serializable方式完全不同的支持定制序列化的方式,是指定该类继承自Externalizable接口,但是继承自该接口的类必须明确重写readExternal和writeExternal方法才能实现对象序列化与反序列化,在这两个方法里指定需要序列化和反序列化的属性字段,没有指明的属性将不会被序列化。

下面是提供一个程序示例。

import java.io.*;
public class TestObjSer{public static void main(String[] args) throws Exception{String stuFilePath = "./student.out";String codFilePath = "./coder.out";File file = new File(codFilePath);if(!file.exists()){System.out.println("The serialization file does not exist, which will be created right now!");file.createNewFile();}Student stu = new Student("zhangsan", 17, Gender.MALE, "CSU");Coder coder = new Coder("lisi", 18, Gender.FEMALE, "JAVA");FileInputStream fis = new FileInputStream(file);FileOutputStream fos = new FileOutputStream(file);//folowing two stream can not be disordered, I have no idea why is thisObjectOutputStream oos = new ObjectOutputStream(fos);ObjectInputStream ois = new ObjectInputStream(fis);serObj(oos,coder);deSerObj(ois);}public static void serObj(ObjectOutputStream oos,Object obj) throws Exception {oos.writeObject(obj);oos.close();}public static void deSerObj(ObjectInputStream ois) throws Exception {Person per = (Person)ois.readObject();ois.close();System.out.println(per);}
}/*** the enum type is a special type in Java, which is generated from * class Enum by default and class Enum implements the interface Seralizable* so it can be serialized and all member of enum should be capital*/
enum Gender{MALE,FEMALE
}
/*** superclass should implement Serialzable*/
class Person implements Serializable{private String name;private int age;private Gender gender;public Person(){System.out.println("Non-Arg constructor be called!");}public Person(String name, int age, Gender gender){System.out.println("Arg constructor be called!");this.name = name;this.age = age;this.gender = gender;}public String getName() {return this.name;}public int getAge() {return this.age;}public Gender getGender(){return this.gender;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setGender(Gender gender){this.gender = gender;}public String toString(){return "Per(name = " + this.getName() + ", age = " + this.getAge() + ", gender = " + this.getGender() +")";}
}
class Student extends Person{//use transient to avoid the field school be serializedprivate transient String school;public Student(){super();}public Student(String name, int age, Gender gender, String school){super(name, age, gender);this.school = school;}public String getSchool() {return this.school;}public void setSchool(String school) {this.school = school;}public String toString(){return "Stu(name = " + this.getName() + ", age = " + this.getAge() + ", gender = " + this.getGender() + ", school = " + this.getSchool() +")";}private void writeObject(ObjectOutputStream oos) throws IOException {oos.defaultWriteObject();//call superoos.writeObject(school);}private void readObject(ObjectInputStream ois) throws Exception{ois.defaultReadObject();//call superthis.school = (String)ois.readObject();}
}
class Coder extends Person implements Externalizable {private String language;public Coder(){super();}public Coder(String name, int age, Gender gender, String language){super(name, age, gender);this.language = language;}public String getLanguage() {return this.language;}public void setLanguage(String language) {this.language = language;}public String toString(){return "Cod(name = " + this.getName() + ", age = " + this.getAge() + ", gender = " + this.getGender() + ", language = " + this.getLanguage() +")";}/*** [readExternal description]serialize by this method should * specify field in readExternal and writeExternal method by user,* it is completely different from Serialzable* @param  in                     [description]* @throws IOException            [description]* @throws ClassNotFoundException [description]*/public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {this.setName((String)in.readObject());this.setAge(in.readInt());this.setGender((Gender)in.readObject());this.language = (String)in.readObject();}public void writeExternal(ObjectOutput out) throws IOException {out.writeObject(this.getName());out.writeInt(this.getAge());out.writeObject(this.getGender());out.writeObject(this.language);}
}

上面的程序示例基本展示了Java对象序列化与反序列化的所有知识,还有一些相关知识,希望在这里啰嗦几句:

1)enum属于Java中的特殊类型,凡是enum类型声明的变量都是默认继承自Enum类,且默认具有序列化特性。

2)Java对象序列化采取级联机制,即如果一个对象引用了其它对象作为其属性,那么在序列化时,引用对象也将被序列化。

3)要想从父类继承的成员也被序列化,则父类必须明确支持序列化特性,即继承Serializable接口。

4)Java序列化的底层原理利用的是反射机制,这个将在后续介绍。

5)从其他博客看到的一点,关于单例模式单例对象的序列化,要想实现反序列化后的对象与单例对象相等,一个解决方法就是替代序列化过程,在该类中添加一个readResolve方法:无论是实现Serializable接口,或是Externalizable接口,当从I/O流中读取对象时,readResolve()方法都会被调用到。实际上就是用readResolve()中返回的对象直接替换在反序列化过程中创建的对象,而被创建的对象则会被垃圾回收掉(这句话是别人的)。

转载于:https://my.oschina.net/u/1258323/blog/471670

代码即财富之我学Java对象序列化与反序列化(2)相关推荐

  1. Xson:Java对象序列化和反序列化工具

    1. Xson 介绍  Xson是一个Java对象序列化和反序列化程序.支持Java对象到字节数组的序列化,和从字节数组到Java对象的反序列化.  地址:https://github.com/xso ...

  2. Java对象序列化与反序列化

    什么是序列化与反序列化 当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送: ...

  3. java对象序列化和反序列化,redis存入和获取对象

    最近使用redis发现直接存储序列化后的对象更方便,现提供java序列化和反序列化的代码 1.序列化代码: public static byte[] serialize(Object object) ...

  4. java byte序列化,java对象序列化byte[] and byte[]反序列化对象--转

    import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOExceptio ...

  5. Java 中序列化与反序列化

    一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...

  6. java培训教程分享:Java中怎样将数据对象序列化和反序列化?

    本期为大家介绍的java培训教程是关于"Java中怎样将数据对象序列化和反序列化?"的内容,相信大家都知道,程序在运行过程中,可能需要将一些数据永久地保存到磁盘上,而数据在Java ...

  7. Java对象序列化详解6,Java对象的序列化与反序列化详解

    把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种途径: Ⅰ . 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中 Ⅱ.  在网 ...

  8. java 对象怎么序列化,java对象序列化总结

    java对象序列化小结 百度百科上介绍序列化是这样的: 序列化 (Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储 ...

  9. 关于 Java 对象序列化您不知道的 5 件事

    数年前,当和一个软件团队一起用 Java 语言编写一个应用程序时,我体会到比一般程序员多知道一点关于 Java 对象序列化的知识所带来的好处. 关于本系列 您觉得自己懂 Java 编程?事实上,大多数 ...

最新文章

  1. lumanager mysql_LuManager单独安装mysqli
  2. Django在根据models生成数据库表时报 missing 1 required positional argument on_delete(亲测)
  3. ajax 设置Access-Control-Allow-Origin实现跨域访问
  4. js设置奇偶行数样式
  5. linux servlet 乱码问题,Servlet一次乱码排查后的总结
  6. 老师,对不起,我古诗背串了...
  7. .net excel循环插数据_[PaperReading]MEMC-Net 运动估计和运动补偿网络
  8. 【大数据部落】基于LDA主题模型聚类的商品评论文本挖掘
  9. 她玩游戏好都不准我玩游戏了_我们可以玩游戏吗?
  10. PHP调用MYSQL存储过程实例
  11. Oracle 11g Rac搭建
  12. 河北科技大学校园网设计和实现
  13. 华为云服务器安全组端口开放教程
  14. 8卡gpu服务器是8个芯片,GPU服务器 4GPU 8GPU 运算卡
  15. 河南理工计算机课程表,河南理工大学张威的课程表.doc
  16. umail for linux,U-Mail邮件系统 for CentOS(6.X) x64
  17. idea里面java文件只读,Java只读集合
  18. 区域发展(二)集聚程度衡量
  19. Hive面试题(一)
  20. Tableau参数:自定义周起始时间

热门文章

  1. 都在说GPT-3和AlphaFold,2020没点别的AI技术突破了?
  2. 「仅凭照片就能判断一个人是否犯罪」?这样的研究能发表,LeCun、MIT谷歌等机构的1700名研究者怒了...
  3. 不用写代码就能做高端科学计算,Mathematica推出“人话”版软件
  4. BAT华为美团头条面试考什么?这份GitHub万星资源,告诉你面试题+答案+出题人分析...
  5. qs.parse()、qs.stringify()使用方法
  6. 智能合约不够安全?微软建专项小组从编程语言入手根治
  7. diamond types are not supported at this language level
  8. 分享一个仿就看天气应用源码
  9. Android 开发第四弹:围住神经猫(简单Demo)
  10. 高校网站群建设方案简介