对象序列化
对象序列化的本质实际上就是将内存中所保存的对象数据转换为二进制数据流进行传输的操作。
但并不是所有类的对象都可以直接进行序列化操作,要被序列化的对象所在的类一定要实现java.io.Serializable接口。而且序列化接口里面是没有任何操作方法存在的,因为它只是一个标识接口,表示一种能力。
例:定义一个可以被序列化对象的类
class Book implements Serializable{
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public String toString(){
return "书名:"+this.title+",价格:"+this.price;
}
}
实现了Serializable接口后并不意味着对象就可以实现序列化操作,还需要其他类的支持。
实现序列化与反序列化
- 序列化操作类:java.io.ObjectOutputStream,将对象序列化为指定格式的二进制数据;
- 反序列化操作类:java.io.ObjectInputStream,将序列化的二进制对象信息转换回对象内容。
ObjectOutputStream类的常用方法
No. | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public ObjectOutputStream(OutputStream out) throws IOException | 构造 | 指定对象序列化的输出流 |
2 | public final void writeObject(Object obj) throws IOException | 普通 | 序列化对象 |
ObjectInputStream类的常用方法
No. | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public ObjectInputStream(InputStream in) throws IOException | 构造 | 指定对象反序列化的输入流 |
2 | public final Object readObject() throws IOException,ClassNotFoundException | 普通 | 从输入流中读取对象 |
由上可以发现,序列化对象接收的参数统一为Object,反序列化对象时返回的类型也为Object,所以这两个类可以序列化或反序列化Java中的所有数据类型(Object可以接收所有引用类型,将基本类型自动装箱为包装类后接收)。
例:实现序列化对象操作
package Project.Study.Serializable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Book implements Serializable{//此类可以被序列化
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public String toString(){
return "书名:"+this.title+",价格:"+this.price;
}
}
public class Test1 {
public static void main(String[]args)throws Exception{
ser();
}
public static void ser()throws Exception{
ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(new File(
"d:"+File.separator+"Test"+File.separator+"test1.txt")));
objectOutputStream.writeObject(new Book("Java",66.66));//序列化对象
objectOutputStream.close();
}
}
结果(序列化对象保存的二进制数据):
例:实现反序列化操作
package Project.Study.Serializable;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class Test2 {
public static void main(String[]args)throws Exception{
dser();
}
public static void dser() throws Exception{
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File(
"d:"+File.separator+"Test"+File.separator+"test1.txt")));
Object obj = objectInputStream.readObject();
Book book = (Book)obj; //反序列化对象
System.out.println(book); //转型
objectInputStream.close();
}
}
//结果:
//
transient关键字
在Java中对象最有意义的内容就是对象的属性信息,所以在默认情况下,如果要进行对象的序列化操作,所序列化的一定是对象的属性信息,并且该对象中的所有属性信息都将被序列化。如果某些属性的内容不需要被保存,就可以通过transient关键字定义。
例:定义不需要序列化的属性
package Project.Study.Serializable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Book implements Serializable{
private transient String title; //此属性无法被序列化
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public String toString(){
return "书名:"+this.title+",价格:"+this.price;
}
}
public class Test2 {
public static void main(String[]args)throws Exception{
ser();
}
public static void ser()throws Exception{
ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(new File(
"d:"+File.separator+"Test"+File.separator+"test1.txt")));
objectOutputStream.writeObject(new Book("C++",66.66));//序列化对象
objectOutputStream.close();
}
}
反序列化得出的结果为
我们可以看到title属性的内容没有被保存下来。