首页 > 代码库 > Java 之 I/O 系列 02 ——序列化
Java 之 I/O 系列 02 ——序列化
Java 之 I/O 系列 目录
Java 之 I/O 系列 01 ——基础
Java 之 I/O 系列 02 ——序列化
一 序列化概述
序列化,简单来讲,就是以“流”的方式来保存对象,至于保存的目标地址,可以是文件,可以是数据库,也可以是网络,即通过网络将对象从一个节点传递到另一个节点。
在Java的I/O结构中,有ObjectOutputStream和ObjectInputStream,它们可以实现将对象输出为二进制流,并从二进制流中获取对象,那为什么还需要序列化呢?这需要从Java变量的存储结构谈起,我们知道对Java来说,基础类型存储在栈上,复杂类型(引用类型)存储在堆中,对于基础类型来说,上述的操作时可行的,但对复杂类型来说,上述操作过程中,可能会产生重复的对象,造成错误。
而序列化的工作流程如下:
1)通过输出流保存的对象都有一个唯一的序列号。
2)当一个对象需要保存时,先对其序列号进行检查。
3)当保存的对象中已包含该序列号时,不需要再次保存,否则,进入正常保存的流程。
正是通过序列号的机制,序列化才可以完整准确的保存对象的各个状态。
序列化保存的是对象中的各个属性的值,而不是方法或者方法签名之类的信息。对于方法或者方法签名,只要JVM能够找到正确的ClassLoader,那么就可以invoke方法。
序列化不会保存类的静态变量,因为静态变量是作用于类型,而序列化作用于对象。
用来实现序列化的类都在java.io包中,我们常用的类或接口有:
ObjectOutputStream:提供序列化对象并把其写入流的方法
ObjectInputStream:读取流并反序列化对象
Serializable:一个对象想要被序列化,那么它的类就要实现 此接口
二 序列化示例
先通过一个简单的例子演示一起序列化/反序列化的过程
Book.java
1 public class Book implements Serializable { 2 3 private int isbn; 4 public Book(int isbn){ 5 this.isbn = isbn; 6 } 7 public int getIsbn() { 8 return isbn; 9 }10 public void setIsbn(int isbn) {11 this.isbn = isbn;12 }13 14 public String toString(){15 return "Book [isbn = "+isbn+"]";16 }17 18 }
Student.java
1 public class Student implements Serializable { 2 3 private Book book; 4 private String name; 5 6 public Student(Book book, String name) { 7 this.book = book; 8 this.name = name; 9 10 }11 12 public Book getBook() {13 return book;14 }15 16 public void setBook(Book book) {17 this.book = book;18 }19 20 public String getName() {21 return name;22 }23 24 public void setName(String name) {25 this.name = name;26 }27 28 public String toString() {29 return "Student [bool=" + book + ", name=" + name + "]";30 }31 32 }
Simulator.java
1 /** 2 * 序列化 3 * @ClassName: Simulator 4 * @author Xingle 5 * @date 2014-6-25 下午5:45:00 6 */ 7 public class Simulator { 8 public static void main(String[] args) { 9 new Simulator().go();10 }11 12 private void go() {13 Student student = new Student(new Book(2014), "xingle");14 try {15 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("test"));16 out.writeObject(student);17 System.out.println("object has been written ");18 out.close();19 } catch (FileNotFoundException e) {20 e.printStackTrace();21 } catch (IOException e) {22 e.printStackTrace();23 }24 25 try {26 ObjectInputStream in = new ObjectInputStream(new FileInputStream("test"));27 Student stuRead = (Student) in.readObject();28 System.out.println("object read here");29 System.out.println(stuRead);30 } catch (FileNotFoundException e) {31 e.printStackTrace();32 } catch (IOException e) {33 e.printStackTrace();34 } catch (ClassNotFoundException e) {35 e.printStackTrace();36 }37 38 }39 40 }
运行结果:
object has been written
object read here
Student [bool=Book [isbn = 2014], name=xingle]
可以看到,读取到的对象与保存的对象状态一样。这里有几点需要说明一下: