一、什么是Java序列化?
- 序列化:把Java对象转换为字节序列的过程
- 反序列:把字节序列恢复为Java对象的过程
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a5JUMand-1685168044507)(E:\student\java基础\java序列化和反序列化.png)]
二、为什么需要序列化?
序列化最重要的作用:
-
在传递和保存对象时.保证对象的完整性和可传递性。
-
对象转换为有序字节流,以便在网络上传输或者保存在本地文件中
三、序列化用途
- 序列化使得对象可以脱离程序运行而独立存在,它主要有两种用途
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ds4Sv2x0-1685168044508)(E:\student\java基础\序列化用途.png)]
四、Java序列化实现方式
- Java原生序列化(Java Serialization)
- java.io.ObjectOutputStream
- java.io.ObjectInputStream
- java.io.Serializable
- java.io.Externalizable
- JSON序列化:
- XML序列化:
- Protocol Buffers序列化:
- Kryo序列化:
五、序列化的使用
-
Java原生序列化(Java Serialization)
-
package com.company.xuliehuaone; import java.io.Serializable; public class Person implements Serializable { private String name; private Integer age; private Man man; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Man getMan() { return man; } public void setMan(Man man) { this.man = man; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", man=" + man + '}'; } }
package com.company; import com.company.xuliehuaone.Person; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Main { public static void main(String[] args) throws Exception { Person person = new Person(); person.setAge(10); person.setName("张三"); // 序列化对象到person.txt 文件中 ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("person.txt")); outputStream.writeObject(person); outputStream.flush(); outputStream.close(); // 反序列化person.txt文件内容到 Person对象中 ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("person.txt")); Object o = inputStream.readObject(); inputStream.close(); System.err.println(o); } }
-
-
JSON序列化:
-
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.3</version> <scope>compile</scope> </dependency>
// 核心代码 ObjectMapper objectMapper = new ObjectMapper(); // 序列化 objectMapper.writeValueAsBytes(t); // 反序列化 objectMapper.readValue
-
-
XML序列化:
-
Protocol Buffers序列化:
-
Kryo序列化:
六、serialVersionUID问题
serialVersionUID 意思就是序列化版本号ID,其实每一个实现Serializable接口的类,都有一个表示序列化版本标识符的静态变量,或者默认等于1L,或者等于对象的哈希码。来验证版本是否一致的。如果相同,反序列化成功,如果不相同,就抛出InvalidClassException异常。
八、transient 关键字使用
个实现Serializable接口的类,都有一个表示序列化版本标识符的静态变量,或者默认等于1L,或者等于对象的哈希码。来验证版本是否一致的。如果相同,反序列化成功,如果不相同,就抛出InvalidClassException异常。
八、transient 关键字使用
transient关键字修饰,它可以阻止修饰的字段被序列化到文件中,在被反序列化后,transient 字段的值被设为初始值,比如int型的值会被设置为 0,对象型初始值会被设置为null。