1、序列化
什么事序列化?序列化就是数据保存在磁盘中,或者在网络中传输。这种机制呢?就是用字节来保存对象的信息,包括对象的数据、对象的属性等。把字节序列写到文件之后,就相当于保存了对象的信息。当需要的时候可以将该字节的信息读取回来,重构对象,这个过程就是反序列化。
2、怎么做到序列化和反序列化呢?
对象序列化需要使用ObjectOutputStream
-
ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。
对象反序列化需要使用ObjectInputStream
3、对象序列化例子
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
super();
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;
}
}
要想Student这个类序列化,需要加上序列化接口标识Serializable,这个接口里没有方法,仅仅是是序列化标识。
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
//序列化写入文件:
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("oos.txt"));
Student stu = new Student("钟志文", 19);
oos.writeObject(stu);
oos.close();
//反序列化读取
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("oos.txt"));
Object obj = ois.readObject(); //读取的object一般不知道是什么类型,用Object表示
Student st = (Student)obj; //向下转型为Student对象
System.out.println(st.getName()+","+st.getAge());
ois.close();
}
以上输出结果是钟志文,19
以上是对Student类的序列化和反序列化。在Student类序列化后,反序列化之前这个类没有被修改过,如果中间修改过,那么会抛出异常InvalidClassException。为了解决这个问题,我们需要给被序列化的类加上一个序列版本号serialVersionUID,这个版本号是序列化标记接口Serializable提供.,作用是验证序列化的对象和对应类是否版本匹配。
import java.io.Serializable;
public class Student implements Serializable{
private static final long serialVersionUID = 421L;
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
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;
}
如果对象的某些数据不想被序列化,那么可以使用瞬态关键字transient修饰。
被static修饰的数据也不会被序列化,因为被序列化的数据被持久存储了,而被static修饰的数据在类加载的时候需要使用,序列化的数据是加载类后做类的填充的。
import java.io.Serializable;
public class Student implements Serializable{
//添加序列化版本号
private static final long serialVersionUID = 421L;
//使用static修饰
private static String name;
//使用瞬态关键字修饰
private transient int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
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;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
//反序列化读取
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("oos.txt"));
Object obj = ois.readObject(); //读取的object一般不知道是什么类型,用Object表示
Student st = (Student)obj; //向下转型为Student对象
System.out.println(st.getName()+","+st.getAge());
ois.close();
}
以上代码,控制台输出结果。