序列化(Serialize):java对象存储到文件中,将java对象的状态保持下来的过程 (ObjectOutputStream)
反序列化(DeSerialize):将硬盘数据重新恢复到内存当中,恢复成java对象 (ObjectInputStream)
①如果想要实现序列化,首先把Student这个类实现Serializable接口,这个接口有标识作用,java虚拟机看到这个接口之后,会自动生成一个序列化版本号(自动默认生成)
②java中采用什么机制区分类的?
类名、若类名相同再采用序列化版本号区分类
两个人编写了同一个类,但是这两个类不是同一个类,此时版本号就起到作用了
这两个人的类都实现了Serializable接口,都有默认的序列化版本号,但是它们默认的序列化版本号是不同的,便区分开了
③自动生成的序列化版本号有什么缺点?
代码确定后,后期不可以修改代码。因为修改代码之后需要重新编译,此时会生成一个全新的版本号,然后就不能被反序列化,java虚拟机就会认为是一个全新的类
④ 凡是一个类实现了Serializable接口,建议提供一个固定不变的序列化版本号,这样即使代码修改,java虚拟机也认为是同一个类
例: private static final long serialversionUID = 777777777L;
下面来看ObjectInputStream 和 ObjectOutputStream 的使用
首先创建一个待使用的类
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private String number;
private static final long serialVersionUID=77777777L; //手动序列化版本号
/*private transient int number; 此时这里的number不会被序列化, 因为transient是有利的,不参与序列化的操作*/
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", number='" + number + '\'' +
'}';
}
public Student(String name, String number) {
this.name = name;
this.number = number;
}
public Student() {
}
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class ObjectOutputStreamTest {
public static void main(String[] args) {
ObjectOutputStream oos =null;
List<Student> sList = new ArrayList<>();//这个集合的底层也实现了接口,底层是数组的数据结构
sList.add( new Student("张三","10088") );
sList.add( new Student("李四","10089") );
sList.add( new Student("王五","10090") );
sList.add( new Student("赵六","10091") );
try {
FileOutputStream fos = new FileOutputStream("Student");
oos = new ObjectOutputStream(fos);
oos.writeObject(sList);
oos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package IOTest;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class ObjectOutputStreamTest {
public static void main(String[] args) {
ObjectOutputStream oos =null;
List<Student> sList = new ArrayList<>();//这个集合的底层也实现了接口,底层是数组的数据结构
sList.add( new Student("张三","10088") );
sList.add( new Student("李四","10089") );
sList.add( new Student("王五","10090") );
sList.add( new Student("赵六","10091") );
try {
FileOutputStream fos = new FileOutputStream("Student");
oos = new ObjectOutputStream(fos);
oos.writeObject(sList);
oos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;
public class ObjectInputStreamTest {
public static void main(String[] args) {
ObjectInputStream ois =null;
try {
FileInputStream fis = new FileInputStream("Student");
ois = new ObjectInputStream(fis);
// 此函数会返回一个Object类型的对象,由于传入的集合是List<Student>类型,则进行强制转换就行
List<Student> sList = (List<Student>) ois.readObject();
for(Student student : sList){
System.out.println(student);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(ois!=null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}