1.什么是序列化
序列化:是把类对象变成二进制,并保存到文件,传送到网络或其他可存贮的介质上。
反序列化:就是把文件、网络或其他介质上的类对象序列化后的二进制,再生成类对象
序列化和反序列化对于JVM是独立的,一个类序列化后,可以在另一个JVM上进行反序列化,甚至两个JVM是不同平台上的JVM。
2.序列化的条件
一个类的对象如果想被序列化必须满足两个条件:
- 对象的类必须实现java.io.Serializable接口,该接口没有任何方法,这样没有任何方法的接口被称为“标记接口“,相当于给自已贴上标签,表达自已有某种能力。
- 对象的所在有属性必须是可序列化的,或者被声明为短暂的。
//只要添加implements Serializable就实现了Serializable接口
public class Person implements Serializable{
...
}
变量声明为短暂的:
public transient int temp;
变量temp被声明为短暂的,序列化时则不会保存temp,返序列化时也不会加载该变量的值。
3.序列化的方法
序列化类的对象我们要用到ObjectOutputStream 类,它是高层次的数据流,它们包含序列化对象的方法writeObject,定义如下:
public final void writeObject(Object x) throws IOException
下面我们写一个序列化类的实例:
首先我们定义一个Person类
package serialize;
import java.io.Serializable;
/**
* [简要描述]:
* [详细描述]:
*
* @author Smalight Lv
* @version 1.0, 2021/5/8 21:23
* @since JDK 1.8
*/
public class Person implements Serializable {
private String id;
private String name;
private int age;
public Person(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
该类实现了Serializable接口,可以被序列化。
序列化Person类的代码如下:
package serialize;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* [简要描述]:序列化
* [详细描述]:
*
* @author Smalight Lv
* @version 1.0, 2021/5/8 21:22
* @since JDK 1.8
*/
public class SerializeTest001 {
public static void main(String[] args) {
Person person = new Person("1001","韦小宝", 23);
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
fileOutputStream = new FileOutputStream("person.ser");
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(person);
System.out.println("序列化成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(objectOutputStream != null){
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
序列化成功
在程序java程序所在的目录生成了 person.ser文件,就是Person类对象实例化的结果。
4.反序列化的方法
反序列化类的对象我们要用到 ObjectInputStream类,它是高层次的数据流,它们包含序列化对象的方法readObject,定义如下:
public final Object readObject() throws IOException,ClassNotFoundException
因为readObject返回的是Object类的对象,所以返序列化后要通过强制转换成相关的对象,再使用。
反序列化上面例子中保存的Person类的对象。
package serialize;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* [简要描述]:反序列化
* [详细描述]:
*
* @author Smalight Lv
* @version 1.0, 2021/5/8 21:53
* @since JDK 1.8
*/
public class SerializeTest002 {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
ObjectInputStream objectInputStream = null;
try {
fileInputStream = new FileInputStream("person.ser");
objectInputStream = new ObjectInputStream(fileInputStream);
Person person = (Person)objectInputStream.readObject();
System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(objectInputStream != null){
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
Person{id='1001', name='韦小宝', age=23}
可以看到类的对象被成功的返序列化。