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]

 可以看到,读取到的对象与保存的对象状态一样。这里有几点需要说明一下:

 

 

 

 

 

Java 之 I/O 系列 02 ——序列化,布布扣,bubuko.com

Java 之 I/O 系列 02 ——序列化

上一篇:【Python】网络编程


下一篇:IDEA使用activiti bpmn流程设计器camunda-modeler