javase-io-210510-01
- 序列化
序列化
ObjectOutputStream
ObjectInputStream
序列化和反序列化必须实现 Serializable 接口
Serializable 接口 它只是一个标志性接口
public interface Serializable {
}
标志性接口作用:
标志作用,java虚拟机看见这个类的实现了这个接口,可能对这个类惊醒特殊待遇
虚拟机看到 Serializable 这个接口,会自动生成一个序列化版本号
在Java中采用什么机制来区分类:
1、 首先通过类名进行对比,如果类名不一样,肯定不是一个类
2、 如果类名一样,再怎么进行类的区分 -------> 通过序列化版本号进行区分
例如: people_01 编写了 com.test.Student implements Serializable
people_02 编写了 com.test.Student implements Serializable
不同的人编写了 同一个类名 的 不同的类 这时候就靠序列化版本号区分了
对于java虚拟机来说,java虚拟机可以区分这两个类,因为这两个类都实现Serializable接口
都有默认的序列化版本号,版本号不一样,因此就区分开了
自动生成序列化版本号的缺陷:
一旦代码确定之后,不能后续修改
如果被修改,必然会重新编译,此时会生成全新的序列化版本号
这个时候java虚拟机会认为这是一个全新的类
解决:
将序列化版本号手动写出来,不让他自动生成(例子:Worker.java)
/*
java虚拟机看见Serializable接口之后,会自动生成一个序列化版本号
java虚拟机会默认提供这个序列化版本号
我们把序列化版本号手动写出来,不建议自动生成
java虚拟机识别一个类,先通过类名判断,在通过序列化版本号区分
*/
/*
如果过了几天几年,,,代码被修改了,,源代码会被重新编译
如果不手动写序列化版本号,,编译后生成了全新的字节码文件,并且class文件再次运行时,
java虚拟机生成的序列化版本号也会发生相应的改变
*/
private static final long serialVersionUID = 1l;
Student.java
package com.bgy01;
import java.io.Serializable;
/*
序列化和反序列化必须实现 Serializable 接口
Serializable 接口 它只是一个标志性接口
public interface Serializable {
}
标志性接口作用:
标志作用,java虚拟机看见这个类的实现了这个接口,可能对这个类惊醒特殊待遇
虚拟机看到 Serializable 这个接口,会自动生成一个序列化版本号
这里没有写出来,java虚拟机会默认提供这个序列化版本号
*/
public class Student implements Serializable {
private String name;
private int age;
public Student(){}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
User.java
package com.bgy01;
/*
transient 游离的,,,不参与序列化
*/
import java.io.Serializable;
public class User implements Serializable {
private transient String name;
private int age;
private String address;
public User(){}
public User(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
Worker.java
package com.bgy01;
import java.io.Serializable;
public class Worker implements Serializable {
/*
java虚拟机看见Serializable接口之后,会自动生成一个序列化版本号
java虚拟机会默认提供这个序列化版本号
我们把序列化版本号手动写出来,不建议自动生成
java虚拟机识别一个类,先通过类名判断,在通过序列化版本号区分
*/
/*
如果过了几天几年,,,代码被修改了,,源代码会被重新编译
如果不手动写序列化版本号,,编译后生成了全新的字节码文件,并且class文件再次运行时,
java虚拟机生成的序列化版本号也会发生相应的改变
*/
private static final long serialVersionUID = 1l;
private String name;
public Worker() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Worker{" +
"name='" + name + '\'' +
'}';
}
}
Demo01.java
package com.bgy01;
/*
序列化
*/
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Demo01 {
public static void main(String[] args) throws IOException {
// 创建java对象
Student s = new Student("白光一",22);
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student"));
// 序列化对象
oos.writeObject(s);
// 刷新
oos.flush();
// 关闭
oos.close();
}
}
Demo02.java
package com.bgy01;
/*
反序列化
*/
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Demo02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student"));
// 开始反序列化,,读
Object obj = ois.readObject();
// 反序列化回来就是一个student对象,会自动调用Student的toSting()方法
System.out.println(obj);
// 关闭
ois.close();
}
}
Demo03.java
package com.bgy01;
/*
可以序列化多个对象
*/
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class Demo03 {
public static void main(String[] args) throws IOException {
// 参与序列化的ArrayList集合以及集合中的Student都要实现java.io.Serializable接口
List<Student> sList = new ArrayList<Student>();
sList.add(new Student("bgy01",22));
sList.add(new Student("bgy02",23));
sList.add(new Student("bgy03",24));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student01"));
// 序列化
oos.writeObject(sList);
oos.flush();
oos.close();
}
}
Demo04.java
package com.bgy01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;
public class Demo04 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student01"));
Object obj = ois.readObject();
System.out.println(obj instanceof List);
// 读
List<Student> sList = (List<Student>) obj;
for (Student s : sList) {
System.out.println(s);
}
// 关闭流
ois.close();
}
}