(1)什么是序列化和反序列化?
Java序列化:将java对象转换为二进制字节序列的过程。
java反序列化:将二进制字节序列恢复为java对象的过程。
对象序列化的更详细的描述:在传递和保存对象的时候,保存对象的可传递性和完整性。序列化是把对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了java对象的状态以及相关的描述信息。序列化机制的核心作用就是对象状态的保存和重建。
对象反序列化的更详细的描述:客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。
(2) 为什么需要序列化和反序列化?
当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等,而这些数据都会以二进制序列的形式在网络上传送。
当两个java进程进行通信时,发送方需要把java对象转换为字节序列,然后在网络中传送;另一方面,接收方需要从字节序列中恢复出java对象。
(3) java序列化的好处?
其一是,实现了数据的持久化,通过序列化可以把数据永久地保存在硬盘上(通常存放在文件中);二是,利用序列化实现远程通信,即在网络上传送数据的字节序列。
(4) 序列化和反序列化的底层实现原理
1、一个类可以通过实现java.io.Serializable接口获得串行化。不实现这个接口的类不会使任何状态序列化或反序列化。序列化类的所有子类型都是序列化的。序列化接口没有任何方法或属性,并且仅仅用于识别可序列化的语义。
* @author unascribed
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @see java.io.ObjectOutput
* @see java.io.ObjectInput
* @see java.io.Externalizable
* @since JDK1.1
*/
public interface Serializable {
}
2、通过ObjectOutputStream的writeObject方法对对象进行序列化,通过ObjectInputStream中的readObject方法对序列进行反序列化。
3、虚拟机是否允许反序列化,看两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID
),若一致,则允许反序列化,否则,不允许反序列化。
4、static和transient修饰的变量不被序列化。
5、java实现代码如下:
//职工类
package com.dd.serializable;
import java.io.Serializable;
public class Employee implements Serializable{
public String name;
public String address;
public transient int SSN;//不想序列化的字段,声明为transient,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
public int number;
public void mailCheck(){
System.out.println("mailing a check to"+name+" "+address);
}
}
//序列化类
package com.dd.serializable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializeTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Employee e = new Employee();
e.name = "Gao Yue";
e.address = "dongbeidaxue";
e.SSN = 111222333;
e.number = 123;
try{
FileOutputStream fileOut = new FileOutputStream("D:/result.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);//重要
out.close();
fileOut.close();
System.out.println("对象序列化成功");
}catch(IOException i){
i.printStackTrace();
}
}
}
//反序列化类
package com.dd.serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class DeserializeTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Employee e = null;
try{
FileInputStream fileIn = new FileInputStream("D:/result.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee)in.readObject();//重要
in.close();
fileIn.close();
System.out.println("对象反序列化成功");
}catch(IOException i){
i.printStackTrace();
}catch(ClassNotFoundException o){
System.out.println("Employee class not found");
o.printStackTrace();
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}