内容简介:知识点:1)序列化概念2)实现序列化手段
知识点:
1)序列化概念
2)实现序列化手段
3)序列化实现深克隆
4)主流序列化手段及操作
Java的序列化机制 Sericalize接口 存在的问题
1)序列化数据结果比较大 传输效率低
2)不能跨语言对接
后续xml编码格式的对象序列化机制成为了主流。
1)多语言
2)便于理解
Json
HTTP RESTful
基于二进制序列化框架 MessagePack
使用恰当的序列化协议不仅可以提高系统的通用性,强壮性,安全性,优化性能,同时能让系统更加易于调试和扩展。
把对象转化为字节序列的过程称为对象的序列化,反之就是对象的反序列化。
1)实现一个序列化操作 首先定义一个对象的类【实现序列化操作需要继承sericalize接口】
package com.llf.sericalizeTest; import java.io.Serializable; public class Person implements Serializable{ private static final long serialVersionUID = -8102469415223443135L; private String Name; private int age; public String getName() { return Name; } public void setName(String name) { Name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 复制代码
写一个测试类,首先我们提供序列化它的方法
然后执行能在相应的地方发现这个person文件生成
然后我们增加其反序列化的操作,并且把文件中反序列化对象中的我们赋值的拿出来
package com.llf.sericalizeTest; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SericalizeDemo { public static void main(String[] args) { //序列化操作 SericalizePerson(); //反序列化操作 DeSericalizePerson(); } /** * 序列化Person类 */ private static void SericalizePerson(){ try { //生成序列化二进制文件的地址 ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(new File("person"))); Person person=new Person(); person.setName("CQ"); person.setAge(18); os.writeObject(person); System.out.println("序列化成功!"); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void DeSericalizePerson(){ try { ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("person"))); try { Person person=(Person) ois.readObject(); System.out.println("名字叫 "+person.getName()); System.out.println("年龄是 "+person.getAge()); System.out.println("反序列化成功!"); ois.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 复制代码
ObjectInputStream :读取指定的字节数据转化为对象
serialVesionUID 的作用: 1)保证序列化对象和反序列化对象是同一个 序列化会有个版本号,如果没有这个的话,会生成新的。 2)静态变量的序列化
序列化不保存静态变量状态
序列化之后然后修改一个静态变量的值然后在反序列化发现对象的值已经变成修改后的值。
Transient 关键字
修饰的属性不参与序列化
序列化的父子类问题:
如果父类没有实现序列化,而子类实现序列化,那么父类中的成员没办法做序列化操作。
序列化的存储规则:
对同个对象进行多次写入,打印出的第一次存储结果和第二次存储结果只多了5个字节的引用关系,不会导致文件累加。
序列化实现深度克隆
1)浅克隆 :复制对象,不复制对象的引用
2)深克隆 :复制对象,复制对象的引用
序列化实现深克隆
package com.llf.sericalizeClone; import java.io.Serializable; public class Teacher implements Serializable{ /** * */ private static final long serialVersionUID = -6957411933291636976L; private String Name; public String getName() { return Name; } public void setName(String name) { Name = name; } @Override public String toString() { return "Teacher [Name=" + Name + "]"; } } 复制代码
package com.llf.sericalizeClone; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Student implements Serializable{ /** * */ private static final long serialVersionUID = -6029082021501636342L; private String Name; private int age; private Teacher teacher; public String getName() { return Name; } public void setName(String name) { Name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } public Object deapClone(){ ByteArrayOutputStream os=new ByteArrayOutputStream(); ObjectOutputStream oos=null; ByteArrayInputStream is=null; ObjectInputStream ois = null; try { //序列化 oos=new ObjectOutputStream(os); oos.writeObject(this); //反序列化 is=new ByteArrayInputStream(os.toByteArray()); ois=new ObjectInputStream(is); try { return ois.readObject(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); }finally { try { ois.close(); is.close(); oos.close(); os.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } @Override public String toString() { return "Student [Name=" + Name + ", age=" + age + "]"; } } 复制代码
package com.llf.sericalizeClone; public class CloneDemo { public static void main(String[] args) { Teacher teacher=new Teacher(); teacher.setName("LLF"); Student student=new Student(); student.setName("CQ"); student.setAge(18); student.setTeacher(teacher); Student student2=(Student) student.deapClone();//克隆一个对象 System.out.println(student); System.out.println(student2); } } 复制代码
总结: 1)在 java 中,只要一个类实现了java.io.serializable接口,那么她就可以被序列化
2) 通过objectoutputstream和objectinputstream对对象进行序列化和反序列化
3)对象是否被反序列化,不仅取决于对象的代码是否一致,同样还有一个重要因素(UID)
4)序列化不保存静态变量
5)要想父类对象也参与序列化操作,必须要让父类也实现serializable接口
6)Transient主要是控制控制变量是否能被序列化。如果没有被序列化的成员变量反序列化后会被设置为初始值。
7)通过序列化操作实现深度克隆。
当前主流的序列化技术有哪些
JSON
Hessian(2)
xml
protobuf
kryo
msgpack
FST
thrify
protostuff
avro
演示几种序列化手段的demo
首先是JSON
1)JSON
首先pom文件中引入jar包
<dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> 复制代码
然后代码
package com.llf.serialiableJSON; import java.io.IOException; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import com.llf.sericalizeTest.Person; public class JsonDemo { //初始化对象 private static Person init(){ Person person=new Person(); person.setName("张三"); person.setAge(18); return person; } public static void main(String[] args) { executeWithJackson(); } @SuppressWarnings("unused") private static void executeWithJackson(){ Person person=init(); ObjectMapper mapper=new ObjectMapper(); byte[] writeBytes=null; long start=System.currentTimeMillis(); for(int i=0;i<100;i++){ try { //序列化 writeBytes=mapper.writeValueAsBytes(person); } catch (JsonGenerationException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("JSON 序列化 "+(System.currentTimeMillis()-start)+"ms : 总大小为-->"+writeBytes.length); //反序列化 try { Person person2=mapper.readValue(writeBytes, Person.class); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 复制代码
同样的阿里也是实现了一个jar包 fastjar
我们比较下俩者的耗时 遍历10万次以下是jackson快而10万以上是fastjson快。
package com.llf.serialiableJSON; import java.io.IOException; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import com.alibaba.fastjson.JSON; import com.llf.sericalizeTest.Person; public class JsonDemo { //初始化对象 private static Person init(){ Person person=new Person(); person.setName("张三"); person.setAge(18); return person; } public static void main(String[] args) { executeWithJackson(); executeWithFastJson(); } @SuppressWarnings("unused") private static void executeWithJackson(){ Person person=init(); ObjectMapper mapper=new ObjectMapper(); byte[] writeBytes=null; long start=System.currentTimeMillis(); for(int i=0;i<100000;i++){ try { //序列化 writeBytes=mapper.writeValueAsBytes(person); } catch (JsonGenerationException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("jackson JSON 序列化 "+(System.currentTimeMillis()-start)+"ms : 总大小为-->"+writeBytes.length); //反序列化 try { Person person2=mapper.readValue(writeBytes, Person.class); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void executeWithFastJson(){ Person person=init(); String text=null; long start=System.currentTimeMillis(); for(int i=0;i<100000;i++){ //序列化 text=JSON.toJSONString(person); } System.out.println("fastjson JSON 序列化 "+(System.currentTimeMillis()-start)+ "ms : 总大小为-->"+text.getBytes().length); //反序列化 Person person2=JSON.parseObject(text, Person.class); } } 复制代码
首先引入jar包,这是百度开发的一个jar包
<dependency> <groupId>com.baidu</groupId> <artifactId>jprotobuf</artifactId> <version>2.1.2</version> </dependency> 复制代码
我们先定义注解
然后序列化和反序列化
protobuf优势就是字节数少,非常适合网络传输。
hessian 序列化 定义方法
字节比较多,但是耗时很低
我们看下各个序列化手段的耗时和字节对比
package com.llf.sericalizeTest; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SericalizeDemo { public static void main(String[] args) { //序列化操作 SericalizePerson(); //反序列化操作 DeSericalizePerson(); } /** * 序列化Person类 */ private static void SericalizePerson(){ try { //生成序列化二进制文件的地址 ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(new File("person"))); Person person=new Person(); person.setName("CQ"); person.setAge(18); os.writeObject(person); System.out.println("序列化成功!"); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void DeSericalizePerson(){ try { ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("person"))); try { Person person=(Person) ois.readObject(); System.out.println("名字叫 "+person.getName()); System.out.println("年龄是 "+person.getAge()); System.out.println("反序列化成功!"); ois.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Redis 分布式锁遇到的序列化问题
- Java 序列化反序列化对比
- python 序列化和反序列化
- json序列化和反序列化
- golang gencode 序列化/反序列化数据
- python的序列化和反序列化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
编译原理
Alfred V.Aho、Jeffrey D.Ullman、Ravi Sethi / 李建中 / 机械工业出版社 / 2003-8 / 55.00元
《编译原理》作者Alfred V.Aho、Ravi Sethi和Jeffrey D.Ullman是世界著名的计算机 科学家,他们在计算机科学理论、数据库等很多领域都做出了杰出贡献。《编译原理》 是编译领域无可替代的经典著作,被广大计算机专业人士誉为“龙书”。《编译原理》一 直被世界各地的著名高等院校和科研机构(如贝尔实验室、哥伦比亚大学、普 林斯顿大学和斯坦福大学等)广泛用作本科生和研究生编译原理......一起来看看 《编译原理》 这本书的介绍吧!