什么情况下需要序列化?
A)当你想把的内存中的对象写入到硬盘的时候;
比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口;
B)当你想用套接字在网络上传送对象的时候;(注意套接字就如手机,如要socket与serversocket)
在进行java的Socket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口;最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输。
C)当你想通过RMI传输对象的时候;
如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。
为什么需要序列化和反序列化?
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
1) 持久化:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;比如:休眠的实现。以后服务器session管理,hibernate将对象持久化实现。
2) 网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信,对象传递。
序列化涉及的类和接口:
java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable接口的类的对象才能被序列化。
序列化/反序列化的步骤和简单测试:
1. 将类Person的实例进行序列化和反序列化:
a) Person类实现Serializable接口:
public class Person implements Serializable{
int age;
boolean bool;
String name;
public Person(int age,boolean bool,String name){
super();
this.age=age;
this.bool=bool;
this.name=name;
}
b) 通过ObjectOutputStream将Person对象的数据写入到文件中,即序列化。
Person person=new Person(20,true,"aa");
FileOutputStream fos=null;
ObjectOutputStream oos=null;
try {
fos=new FileOutputStream("d:/m.txt");
oos=new ObjectOutputStream(fos);
oos.writeObject(person);
oos.writeObject(new Date());
oos.flush();
oos.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c)通过ObjectInputStream将文件中二进制数据反序列化成Person对象:
FileInputStream f=null;
ObjectInputStream o=null;
try {
f=new FileInputStream("d:/m.txt");
o=new ObjectInputStream(f);
Person p=(Person)o.readObject();
Date d=(Date)o.readObject();
System.out.println(p.age+p.name+p.bool+d);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}