先来说一下什么是序列化与反序列化?
序列化:
永久的保存对象,保存对象的字节序列到本地文件中
反序列化:
将保存到本地文件中的对象读取到内存中,还原成这个对象
如何实现序列化与反序列化?
一个类如果想被序列化,则必须实现java.io.Serializable接口,这个接口没有定义任何方法,是一个标志性接口,当一个类实现了该接口,就表示这个类的对象是可以被序列化的
下面说一下序列化的时候,需要注意的问题
1.当一个对象被序列化的时候,只保存对象的非静态成员变量,因为静态成员与方法是属于类的成员
2.如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存
3.如果一个可序列化对象包含了某个不可序列化对象的引用,那么整个序列化是会失败的,并且会抛出一个NotSerializableException,我们可以将这个引用标记为transient,表示为短暂的,此时该变量就无法被序列化,然后对象依旧可以被序列化
下面介绍一下序列化与反序列化用到的两个对象与方法
1.序列化对象与方法
上面序列化是要把对象写出去,因此就要用到ObjectOutputStream流
这里还需要说明一点的就是,序列化一般在外部存储文件,该文件的扩展名一般就叫.ser
2.反序列化的对象与方法
下面我们来看代码实例
先来看我们需要序列化的一个类
Person
package domain;
import java.io.Serializable;
import java.util.Date;
public class Person implements Serializable {
String name;
int age;
String gender;
//添加了一个短暂属性,表明这个字段不可别序列化
transient Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
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 getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
序列化类SerializeTest1.java
package test;
import domain.Person;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
public class SerializeTest1 {
public static void main(String[] args) throws IOException {
Person p = new Person();
p.setName("王二麻子");
p.setAge(520);
p.setGender("男");
p.setBirthday(new Date());
//建立一个序列化对象
FileOutputStream fis = new FileOutputStream("D:/w.ser");
ObjectOutputStream oos = new ObjectOutputStream(fis);
oos.writeObject(p);
oos.close();
fis.close();
}
}
这个就会在指定位置给我们产生一个文件
但是你不要打开这个看啊,因为这个肯定是乱码,毕竟是一个序列化文件,属于正常情况
然后去看我们的反序列化文件Deserialize.java
package test;
import domain.Person;
import java.io.*;
public class DeserializeTest1 {
public static void main(String[] args) {
//将文件进行反序列化
Person p = null;
//建立一个反序列化对象
//这里是.ser序列化的文件
FileInputStream fis = null;
ObjectInputStream objectInputStream = null;
try {
fis = new FileInputStream("D:/w.ser");
objectInputStream = new ObjectInputStream(fis);
p = (Person) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//上面就会反序列化之前我们在文件中存放的对象
//然后访问一下之前创建的对象
System.out.println("Name: " + p.getName());
System.out.println("age: " + p.getAge());
System.out.println("gender: " + p.getGender());
System.out.println("birthday: " + p.getBirthday());
}
}
运行结果:
这里在说一下为什么birthday是NULL,不是之前设置了值吗?你忘啦,我们添加了transient短暂属性,所以它不会被序列化的。
再见。