序列化是什么:把一个java对象转化为二进制对象,并保存到硬盘,或在网络上传输。反序列化就是把序列化的二进制对象读到内存中。 做用:
一、减小内存占用或网络传输。好比web容器中的session,当session数量过大好比10W+链接时会将一部分session序列化到硬盘,须要时再读取。
二、当两个远程进程通讯,能够将对象序列化后传给另外的进程,另外的进程再反序列化获取对象值。
代码示例:
Person类 实现 Serializable 接口 `package com.seriable;html
import java.io.Serializable;java
/**git
Desc:github
@author: lisha 2018/7/25 14:29 */ public class Person implements Serializable {web
/**数组
public int getAge() { return age; }网络
public String getName() { return name; }session
public String getSex() { return sex; }jvm
public void setAge(int age) { this.age = age; }测试
public void setName(String name) { this.name = name; }
public void setSex(String sex) { this.sex = sex; } }`
测试类测试序列化
`public class MainTest {
public static void main(String[] args) throws Exception { // 序列化Person对象 SerializePerson(); // 反序列Perons对象
// Person p = DeserializePerson(); // System.out.println(MessageFormat.format("name={0},age={1},sex={2}", // p.getName(), p.getAge(), p.getSex())); }
/** * MethodName: SerializePerson * Description: 序列化Person对象 * [@author](https://my.oschina.net/arthor) xudp * [@throws](https://my.oschina.net/throws) FileNotFoundException * [@throws](https://my.oschina.net/throws) IOException */ private static void SerializePerson() throws FileNotFoundException, IOException { Person person = new Person(); person.setName("ls"); person.setAge(28); person.setSex("男"); // ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操做 ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream( new File("E:/Person.txt"))); oo.writeObject(person); System.out.println("Person对象序列化成功!"); oo.close(); } /** * MethodName: DeserializePerson * Description: 反序列Perons对象 * [@author](https://my.oschina.net/arthor) xudp * @return * @throws Exception * @throws IOException */ private static Person DeserializePerson() throws Exception, IOException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream( new File("E:/Person.txt"))); Person person = (Person) ois.readObject(); System.out.println("Person对象反序列化成功!"); return person; }
}`
生成txt文件
反序列化是同样的,将txt文件读到java对象中 serialVersionUID 这个在Person中是序列化id,用来匹配校验序列化的对象和反序列化生成的对象必须是同一个对象。 /** * 序列化ID */ //private static final long serialVersionUID = -5809782578272943999L;
JDK自带的序列化有哪些缺点呢?
效率很低,JDK提供的序列化技术相对而已效率较低。在转换二进制数组过程当中空间利用率较差。 参考网址https://blog.csdn.net/canot/article/details/53750443
github上序列化效率对比,都是英文的,https://github.com/eishay/jvm-serializers/wiki
本文参考网址
http://www.javashuo.com/article/p-zwszwxvq-ds.html
JDK自带序列化注意事项
一、若是子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,不然会抛InvalidClassException异常。
二、静态变量不会被序列化,那是类的“菜”,不是对象的。
三、transient关键字修饰变量能够限制序列化。
四、虚拟机是否容许反序列化,不只取决于类路径和功能代码是否一致,一个很是重要的一点是两个类的序列化 ID 是否一致,就是 private static final long serialVersionUID = 1L。
五、Java 序列化机制为了节省磁盘空间,具备特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用。反序列化时,恢复引用关系。
六、序列化到同一个文件时,如第二次修改了相同对象属性值再次保存时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,所以只保存第二次写的引用,因此读取时,都是第一次保存的对象。读者在使用一个文件屡次 writeObject 须要特别注意这个问题(基于第5点)。
参考网址:https://blog.csdn.net/chenleixing/article/details/43833805