文章目录
1.概述
- java是面向对象编程,对象如何在网络中传递,就需要序列化操作。
- 序列化就是,将对象写入字节流中,使其可以进行网络传输,或者可以,存储在数据库或者文件系统中,当需要的时候可以通过字节流反序列化成对象。
- 将对象的状态信息,转换为可以存储或者传输的形式过程。这样看来,序列化是一种技术手段,为了实现传输的功能。
1.1 什么情况下使用序列化
- 在分布式的情况下,java程序在网络传输中,
- 如: 将A电脑中的数据传输到B电脑中,web中的
json
串传输。
- 如: 将A电脑中的数据传输到B电脑中,web中的
- 跨平台传输数据。
- 如:windows平台 向 Linux平台中传输数据。
- 在网络传输数据,计算机可以简单的认为只认二进制形式数据,如将对象的状态(主要指属性)序列化,存放到临时或者持久的存储区中,当使用的时候,通过反序列化,重写创建该对象。
1.2. 注意事项
- 需要实现序列化的文件必须实现
Serializable接口
该接口。- 相当于,开启序列化功能。
- 每一个序列化文件都会生成一个唯一序列的id。
- 编译器会,自动生成该id唯一值。
- 在反序列化时,如果和序列化的版本号不一致,无法完成反序列化。
- 关键字注意:
static
修饰的类,静态类,不能被序列化。transient
修饰的属性,不能序列化。
2. 流对象
2.1 创建对象
- 实现序列化的流对象。相当于把java对象变成字节流的形式传出去,或者从一个字节流中恢复一个java对象。
1.ObjectOutputStream(OutputStream out);
通过 writeObject()方法做序列化操作。 写出的动作。
把对象的信息,按照固定的格式转成一串字节值输出并持久保存到磁盘。
2.ObjectInputStream(InputStream in);
通过 readObject() 方法做反序列化操作。 读的动作。
读取磁盘中之前序列化好的数据,重新恢复成对象。
3. 案例序列化的使用
3.1 创建对象
- 既然要写对象,就要创建对象!还记得怎么创建对象么?
- 要创建UUID值。
/**
javabean对象。如果没有实现序列化接口会怎么样!? java.io.NotSerializableException
*/
public class Student implements Serializable {
private static final long serialVersionUID = -4507528408053208066L;//一旦生成不要改动。
//1.创建属性
private String name;
private int age;
//2.无参构造方法
public Student() {
}
//2.1 含参数构造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//3.对外提供访问方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//1.重写 toString()
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3.1 序列化 写出操作
- 创建对象,使用
writeObject()
方法。 - 注意: 对象要实现序列化接口,并创建uuid值(反序列化需要使用)(idea需要设置)。
- 写出是持久化写到磁盘中。
public static void main(String[] args) {
File file = new File("D://a.txt");
//1.写出
try( ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream(file));) {
//2.创建对象
Student s = new Student("周杰伦", 32);
oos.writeObject(s); //写出对象,前提需要实现接口 Serializable
oos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
3.2 反序列化 读取操作
- 为什么要生成UUID?
- 如果序列化ID和反序列化不一致会怎么样!?
public class Test_Serializable2 {
public static void main(String[] args) {
File file = new File("D://a.txt");
try(ObjectInputStream ois =
new ObjectInputStream(new FileInputStream(file));) {
//1.将文件中的对象反序列化
Object o = ois.readObject();//必须要抛出ClassNotFoundException。
System.out.println(o);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
-
输出结果:
Student{name='周杰伦', age=32}
3.3 uuid不一致 或 当属性有关键字
- 如果uuid 序列化和反序列化不一致时!一旦生成就不要改动,或者让jvm自己生成
//1.private static final long serialVersionUID = -4507528408053208066L;
private static final long serialVersionUID = -450752840805320806L;//该如下在进行序列化读取
//1.报错 uuid不一致。
java.io.InvalidClassException: com.java.oop.seriz.Student;
local class incompatible:
stream classdesc serialVersionUID = -4507528408053208066, local class serialVersionUID = -450752840805320806
- 当属性上
transient
时 该 属性 无法序列化。- 写出到磁盘,在从磁盘读取。
// 2. 在属性加上关键字 transient时
//2.1.创建属性
private transient String name;
private int age;
Student{name='null', age=32}