java中的序列化解析
作者:grace.free
一、序列化
为了将对象进行网络传输或者是持久化,我们需要将对象的状态信息转换为可以存储或者传输的形式。
这个转换的过程就叫序列化
jre能力
Jre本身提供了序列化的支持,我们可以调用outputStream的writeObject方法
如果让Java帮我们做的话,我们需要实现Serializable接口,这个接口是一个mini接口,没有需要实现的方法,说白了,只是做一个标记。
package freeedu.test; import java.io.*; /** * @author 木子的昼夜编程 */ public class SerTest { public static void main(String[] args) throws Exception { // 创建对象 Person p = new Person("小花", 18, "女"); // 创建ObjectOutputStream ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("E:/MyNote/obj/Person.obj")); // 持久化 outputStream.writeObject(p); } } // 人 未实现Serializable class Person{ String name; int age; String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
读者朋友仔细看看,这样写对吗?
一般问你对不对,那肯定就是不对啦!
使用JRE自带序列化功能,被序列化的对象必须实现Serializable,否则就会报错
下面才是正确的写法:
package freeedu.test; import java.io.*; /** * @author 木子的昼夜编程 */ public class SerTest { public static void main(String[] args) throws Exception { // 创建对象 Person p = new Person("小花", 18, "女"); // 创建ObjectOutputStream ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("E:/MyNote/obj/Person.obj")); // 持久化 outputStream.writeObject(p); } } // 人 实现Serializable class Person implements Serializable{ String name; int age; String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
执行成功之后,看一看文件内容?
看不懂?没关系,我们可以反序列化,再看内容
package freeedu.test; import java.io.*; /** * @author 木子的昼夜编程 */ public class DesTest { public static void main(String[] args) throws Exception { // 创建ObjectInputStream ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("E:/MyNote/obj/Person.obj")); // 读取对象 Object o = inputStream.readObject(); // 判断对象持久化对象是不是Person if (o instanceof Person) { // 如果是的话 强转 Person p = (Person) o; // 打印信息 System.out.println(p.age); System.out.println(p.name); System.out.println(p.gender); } } }
Serializable
可以看到,他只是一个接口,没有任何需要实现的内容。
其他
当然了,这只是Java自带的序列化,我们平时网络传输等会使用到很多其他序列化。
比如:
- Json序列化
- 谷歌Gson的Json 、阿里的FastJson 、Jackson 等
- ProtoBuff序列化 据说做游戏的很多用这个 是谷歌出的 会大大节省传输流量
二、Serializable 接口
我们看java自带序列化,需要实现一个Serializable,而实现这个接口,要求我们需要添加一个serialVersionUID 属性,就像下边这样
// 人 class Person implements Serializable{ // 定义serialVersionUID private static final long serialVersionUID = 8940196742313994740L; String name; int age; String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
如果你不定义这个serialVersionUID,jdk会根据序列化类的信息,比如字段等自动生成一个,但是你如果修改了这个类(比如添加字段),然后再反序列化没有修改之前序列化的内容就会报错
比如我们修改一下Person类,然后反序列化一下上边那个文件
class Person implements Serializable{ String name; int age; String gender; String aaaaaaa; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
如果Person类在序列化的时候定义了serialVersionUID,那么就不会出现这个问题
这个serialVersionUID很像是我们的银行卡号,如果你的银行卡没卡号,只是根据你的手机号,或者是你的姓名进行绑定,那么当你手机号变更了,或者名称变更了,那么就对应不上你的卡了。所以我们银行卡都有一个卡号,这个卡号随银行卡产生而产生,随银行卡注销而注销。
到此这篇关于java中的序列化解析的文章就介绍到这了,更多相关java序列化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!