序列化的初步理解

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

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

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

定义person对象
package test.vo;

import java.io.Serializable;

/**
 * 对象要想被序列化,必须实现Serializable接口
 * @author tim.syh
 *
 */
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 + "]";
	}
	
}
 序列化和反序列化
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的概念,和这个是一样的意思。

作用

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

  1. 像示例中一样,可以把一个对象保存在硬盘中(就是各种文件呀),然后拿着它到处晃悠了。想用的时候再反序列化一下就又回来了。
  2. 把对象弄成文件之后就可以在网络上进行传输了,现在很流行的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来说,还是显得臃肿了一点。不过只要你理解了序列化的本质,无所谓用什么形式传输啦。

    技术就是这样子,理解了可以随便玩。

猜你喜欢

转载自friendsyh-126-com.iteye.com/blog/2257990