Java序列化是指将Java对象转化为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。 当两个进程进行远程通信时,这个通信的数据可以为文本、图片、音频或者视频等,而这些数据都是以二进制的形式进行传送的。而当两个Java进程间进行通信时,进程间对象的传送也是二进制方式传输。这就要用到序列化和反序列化,一方面,发送方需要把这个Java对象转化为字节序列,另一方面接收方要从字节序列中恢复出Java对象。
好处: * 实现了数据的持久化,通过序列化可以把数据永久地存放在硬盘上 * 利用反序列化实现远程通信,即在网络上传送对象的字节序列化
2.1 JDK类库中序列化API - java.io.ObjectOutputStream:表示对象输出流 它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。 -java.io.ObjectInputStream:表示对象输入流- 它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。 - 序列化步骤: 步骤一:创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流: ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\objectfile.obj”)); 步骤二:通过对象输出流的writeObject()方法写对象: out.writeObject(“Hello”); out.writeObject(new Date()); - 反序列化步骤: 步骤一:创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流: ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\objectfile.obj”)); 步骤二:通过对象输出流的readObject()方法读取对象: String obj1 = (String)in.readObject(); Date obj2 = (Date)in.readObject();
2.2 实现序列化接口 只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以 采用默认的序列化方式 。
2.3 案例
import java.io.Serializable; public class Student implements Serializable { private static final long serialVersionUID = 4603642343377807741L; private String name; private char sex; private int year; private double gpa; public Student() { } public Student(String name,char sex,int year,double gpa) { this.name = name; this.sex = sex; this.year = year; this.gpa = gpa; } public void setName(String name) { this.name = name; } public void setSex(char sex) { this.sex = sex; } public void setYear(int year) { this.year = year; } public void setGpa(double gpa) { this.gpa = gpa; } public String getName() { return this.name; } public char getSex() { return this.sex; } public int getYear() { return this.year; } public double getGpa() { return this.gpa; } }把Student类的对象序列化到文件D:\student.txt,并从该文件中反序列化,向console显示结果。代码如下:
import java.io.*; public class UseStudent { public static void main(String[] args) { Student st = new Student("Tom",'M',20,3.6); File file = new File("D:\\student.txt"); try { file.createNewFile(); } catch(IOException e) { e.printStackTrace(); } try { //Student对象序列化过程 FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(st); oos.flush(); oos.close(); fos.close(); //Student对象反序列化过程 FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); Student st1 = (Student) ois.readObject(); System.out.println("name = " + st1.getName()); System.out.println("sex = " + st1.getSex()); System.out.println("year = " + st1.getYear()); System.out.println("gpa = " + st1.getGpa()); ois.close(); fis.close(); } catch(ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }3.serialVersionUID的作用 serialVersionUID字面意思是序列化版本号,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException) serialVersionUID的作用生成方式: 1.一个是默认的1L,比如:private static final long serialVersionUID = 1L; 2.一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段 ++ 为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。 ++
参考博客: http://kb.cnblogs.com/page/515982/ http://blog.csdn.net/abc6368765/article/details/51365838 http://blog.csdn.net/wangloveall/article/details/7992448/ http://kb.cnblogs.com/page/515982/