疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java序列化的初步理解


 

   

  序列化就是把一个对象固化,怎么理解。java中一个对象,比如Person person = new Person(),通过new出一个person对象之后,如果你关闭了JVM(比如说关闭了eclipse),如果你还想用person对象怎么办?简单,我们重新new一个新的一模一样的对象,但是我们必须要上次new这个Person的属性,比如name,sex等,并且这个新new的对象也不可能一模一样的,因为他们是不同时间new出来的,也许这个时间间隔里面JVM还发生变化了呢。

  所以我们需要有一种机制把person永久的保存下来,那就是序列化。通过什么办法序列化,我们最好理解的就是把person记录在一个文档里面(比如txt文件),这样子我下次使用就根据保存的这个txt文件通过程序再次读入程序就行了,这个过程就叫做反序列化。

  请看示例,示例的目的是序列化一个Perosn对象,然后再反序列化回来。

  定义person对象

  Java代码

  package test.vo;

  import java.io.Serializable;

  /**

  * 对象要想被序列化,必须实现Serializable接口

  *

  */

  public class Person implements Serializable{

  private static final long serialVersionUID = -7142264207488774373L;

  private String name;

  private int age;

  public Person(String name, int age) {

  super();

  this.name = name;

  this.age = age;

  }

  public String getName() {

  return name;

  }

  public void setName(String name) {

  this.name = name;

  }

  public int getAge() {

  return age;

  }

  public void setAge(int age) {

  this.age = age;

  }

  @Override

  public String toString() {

  return "Person [name=" + name + ", age=" + age + "]";

  }

  }

  序列化和反序列化

  Java代码 收藏代码

  package test.serializable;

  import java.io.FileInputStream;

  import java.io.FileNotFoundException;

  import java.io.FileOutputStream;

  import java.io.IOException;

  import java.io.ObjectInputStream;

  import java.io.ObjectOutputStream;

  import test.vo.Person;

  public class TestSerializale {

  public static void main(String[] args) throws Exception{

  //定义一个person对象

  Person person = new Person("tim", 20);

  //序列化对象到path目录下,可以看到执行完成之后在D:/temp目录下多了一个person.txt文件

  String path = "D:/temp/person.txt";

  serialiobject(person, path);

  //执行完上面的之后,你可以关闭掉eclipse甚至跑到你隔壁的电脑去执行反序列化的代码

  //当然如果你要去隔壁电脑执行,需要把person.txt文件也拷贝过去哈

  Person p = deSerialiobject("D:/temp/person.txt");

  //打印下结果是 :Person [name=tim, age=20],perosn的信息又回来了。

  System.out.println(p);

  }

  /**

  * 序列化Person对象,生成的字节流存放path目录下去

  * @param person

  */

  private static void serialiobject(Person person, String path) throws Exception{

  //jdk自带的序列化类,把person对象写入到path目录下的文件中

  ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(path));

  oo.writeObject(person);

  oo.close();

  System.out.println("对象序列化成功");

  }

  /**

  * 从文件中去读取对象。

  * @param path 已经序列化的文件的目录

  * @return Person对象

  */

  private static Person deSerialiobject(String path) throws Exception{

  //jdk自带的反序列化类,又把path路径下文件的内容读回成一个对象

  ObjectInputStream oi = new ObjectInputStream(new FileInputStream(path));

  Person p = (Person)oi.readObject();

  oi.close();

  System.out.println("对象反序列化成功!");

  return p;

  }

  }

  你可以自己做实验,当把一个对象序列化之后,你明天再来反序列化,还能够得到昨天新建对象person的信息,这是不是相当于把person这个对象的信息给固化了,这个让你想到了什么?对,ORM的概念,和这个是一样的意思。

  作用

  固化一个对象有什么用呢?这个用处可大了。

  像示例中一样,可以把一个对象保存在硬盘中(就是各种文件呀),然后拿着它到处晃悠了。想用的时候再反序列化一下就又回来了。

  把对象弄成文件之后就可以在网络上进行传输了,现在很流行的websercie首先就是要实现对象能够这样子序列化才行。

  方式

  序列化有很多方式,比如例子中说道的jdk自带的ObjectOutputStream对象(示例就是)啦,其他的第三方的比如比较常见的hessian,Google的Protocal Buffers呀,他们比jdk自带的效率高一些。其实还有更常用的方式那就是xml和json呀。

  说到常用的xml和json,原来也是序列化的一种呀,当然是呀,一个xml和json文件的内容你都可以看成是一个个已经固话的对象,然后就可以进行保存,传输了,如果要用这些对象的时候反序列就OK了。

  xml和json

  在java web系统中,我们经常需要把person对象从A系统传到B系统进行处理,比如webservice这种远程调用,当然,他们已经帮我们实现了这部分网络传输的部分,对于我们来说,就相当是把person对象从A系统通过网络运输到B系统去了,但是实际它在运输之前,肯定要首先把person对象序列化成文本或者流的形式(就是二进制码,文本你要传输最终不也是要转成二进制进行传输吗)运送到B系统,B系统再进行反序列化从而拿到person对象。

  SOUP协议就是用xml的形式传递对象数据,不过现在json越来越流行了,毕竟用xml来传递数据的soup协议比起轻量级的json来说,还是显得臃肿了一点。不过只要你理解了序列化的本质,无所谓用什么形式传输啦。