java_序列化
Posted qrrlinux
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java_序列化相关的知识,希望对你有一定的参考价值。
1.概念
序列化:将对象转化为字节序列的过程
反序列化:将字节序列转化为对象的过程
用途:
A:将对象转化为字节序列保存在硬盘上,如文件中,如文本中的例子就是将person对象序列化成字节序列,存在person.txt文件中
B:网络传输中一般都是以对象序列化的形式存在,在网络的发送/接收两端进行对象的序列化/反序列化
输入/输出的使用:
一般都是针对内存而言,内存--硬盘--》outputStream 从硬盘--内存--》inputStream
具体使用要根据场景来确定
2.example
2.1 无显式的指定UID,采用编译系统自动生成的
Object:
package com.java.baseinfo.knowledge.code.serializable; import java.io.Serializable; public class Person implements Serializable { private int age; private String name; private String sex; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Person{"); sb.append("age=").append(age); sb.append(", name=‘").append(name).append(‘‘‘); sb.append(", sex=‘").append(sex).append(‘‘‘); sb.append(‘}‘); return sb.toString(); } }
object uid
package com.java.baseinfo.knowledge.code.serializable; 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 TestObjSerializeAndDeserialize { public static void main(String[] args) { // 序列化 SerializablePerson(); // 反序列化 //Deserialization(); } private static void SerializablePerson() { Person person = new Person(); person.setAge(10); person.setName("测试"); person.setSex("女"); String path = "src/test/resources/person.txt"; try { FileOutputStream fileOutputStream = new FileOutputStream(new File(path)); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(person); System.out.println("序列化成功"); fileOutputStream.close(); objectOutputStream.close(); } catch (FileNotFoundException e) { System.out.printf("FileNotFoundException====>" + e); } catch (IOException e) { System.out.printf("IOException====>" + e); } } private static Person Deserialization() { try { FileInputStream fileInputStream = new FileInputStream(new File("src/test/resources/person.txt")); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); Person person = (Person) objectInputStream.readObject(); System.out.printf("Deserialization.person===>"+person); } catch (FileNotFoundException e) { System.out.printf("FileNotFoundException====>" + e); } catch (IOException e) { System.out.printf("IOException====>" + e); } catch (ClassNotFoundException e) { System.out.printf("ClassNotFoundException====>" + e); } return null; } }
先序列化,才进行反序列化
Deserialization.person===>Person{age=10, name=‘测试‘, sex=‘女‘}
给person增加字段,再用原来的序列化后的结果,进行反序列化;
package com.java.baseinfo.knowledge.code.serializable; import java.io.Serializable;
public class Person implements Serializable { private int age; private String name; private String sex; // 增加字段测试序列化 private String addText; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddText() { return addText; } public void setAddText(String addText) { this.addText = addText; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Person{"); sb.append("age=").append(age); sb.append(", name=‘").append(name).append(‘‘‘); sb.append(", sex=‘").append(sex).append(‘‘‘); sb.append(", addText=‘").append(addText).append(‘‘‘); sb.append(‘}‘); return sb.toString(); } }
运行结果
IOException====>java.io.InvalidClassException: com.java.baseinfo.knowledge.code.serializable.Person; local class incompatible: stream classdesc serialVersionUID = 6964452789008335213, local class serialVersionUID = -3534890433624150186 Process finished with exit code 0
原因是:之前代码中未显示的指定UID,当Object中新增字段时,编译器又新生成一个UID,于是出现序列化版本不一致的问题;
2.2 显式指定UID
package com.java.baseinfo.knowledge.code.serializable; import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = -3534890433624150186L; private int age; private String name; private String sex; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Person{"); sb.append("age=").append(age); sb.append(", name=‘").append(name).append(‘‘‘); sb.append(", sex=‘").append(sex).append(‘‘‘); sb.append(‘}‘); return sb.toString(); } }
运行上述main函数, 先进行序列化,然后再对object增加属性,再序列化的结果,进行反序列化
package com.java.baseinfo.knowledge.code.serializable; import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = -3534890433624150186L; private int age; private String name; private String sex; // 增加字段测试序列化 private String addText; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddText() { return addText; } public void setAddText(String addText) { this.addText = addText; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Person{"); sb.append("age=").append(age); sb.append(", name=‘").append(name).append(‘‘‘); sb.append(", sex=‘").append(sex).append(‘‘‘); sb.append(", addText=‘").append(addText).append(‘‘‘); sb.append(‘}‘); return sb.toString(); } }
反序列化结果,新增的字段为空值
Deserialization.person===>Person{age=10, name=‘测试‘, sex=‘女‘, addText=‘null‘} Process finished with exit code 0
显式的指定UID,目前常用到的场景是:当object增加的字段时候,不希望反序列化出现异常,即希望类的不同版本对序列化兼容;
等用到其他场景的时候,再更新。。
参考:https://www.cnblogs.com/xdp-gacl/p/3777987.html
以上是关于java_序列化的主要内容,如果未能解决你的问题,请参考以下文章
编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议11~15)
[AndroidStudio]_[初级]_[配置自动完成的代码片段]