Java IO详解(六)------序列化与反序列化(对象流)

File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.htmlhtml

Java IO 流的分类介绍:http://www.cnblogs.com/ysocean/p/6854098.htmljava

Java IO 字节输入输出流:http://www.cnblogs.com/ysocean/p/6854541.html服务器

Java IO 字符输入输出流:https://i.cnblogs.com/EditPosts.aspx?postid=6859242网络

Java IO 包装流:http://www.cnblogs.com/ysocean/p/6864080.html数据结构

 

一、什么是序列化与反序列化?分布式

  序列化:指把堆内存中的 Java 对象数据,经过某种方式把对象存储到磁盘文件中或者传递给其余网络节点(在网络上传输)。这个过程称为序列化。通俗来讲就是将数据结构或对象转换成二进制串的过程ide

  反序列化:把磁盘文件中的对象数据或者把网络节点上的对象数据,恢复成Java对象模型的过程。也就是将在序列化过程当中所生成的二进制串转换成数据结构或者对象的过程post

 

二、为何要作序列化?this

  ①、在分布式系统中,此时须要把对象在网络上传输,就得把对象数据转换为二进制形式,须要共享的数据的 JavaBean 对象,都得作序列化。htm

  ②、服务器钝化:若是服务器发现某些对象很久没活动了,那么服务器就会把这些内存中的对象持久化在本地磁盘文件中(Java对象转换为二进制文件);若是服务器发现某些对象须要活动时,先去内存中寻找,找不到再去磁盘文件中反序列化咱们的对象数据,恢复成 Java 对象。这样能节省服务器内存。

 

三、Java 怎么进行序列化?

  ①、须要作序列化的对象的类,必须实现序列化接口:Java.lang.Serializable 接口(这是一个标志接口,没有任何抽象方法),Java 中大多数类都实现了该接口,好比:String,Integer

  ②、底层会判断,若是当前对象是 Serializable 的实例,才容许作序列化,Java对象 instanceof Serializable 来判断。

  ③、在 Java 中使用对象流来完成序列化和反序列化

    ObjectOutputStream:经过 writeObject()方法作序列化操做

    ObjectInputStream:经过 readObject() 方法作反序列化操做

    

 

 

 第一步:建立一个 JavaBean 对象

public class Person implements Serializable{
	private String name;
	private int 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 + "]";
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}  

 

 第二步:使用 ObjectOutputStream 对象实现序列化

//在根目录下新建一个 io 的文件夹
		OutputStream op = new FileOutputStream("io"+File.separator+"a.txt");
		ObjectOutputStream ops = new ObjectOutputStream(op);
		ops.writeObject(new Person("vae",1));
		
		ops.close();

  咱们打开 a.txt 文件,发现里面的内容乱码,注意这不须要咱们来看懂,这是二进制文件,计算机能读懂就好了。

错误一:若是新建的 Person 对象没有实现 Serializable 接口,那么上面的操做会报错:

    

第三步:使用ObjectInputStream 对象实现反序列化

  反序列化的对象必需要提供该对象的字节码文件.class

InputStream in = new FileInputStream("io"+File.separator+"a.txt");
		ObjectInputStream os = new ObjectInputStream(in);
		byte[] buffer = new byte[10];
		int len = -1;
		Person p = (Person) os.readObject();
		System.out.println(p);  //Person [name=vae, age=1]
		os.close();

  

问题1:若是某些数据不须要作序列化,好比密码,好比上面的年龄?

解决办法:在字段面前加上 transient

private String name;//须要序列化
	transient private int age;//不须要序列化

  那么咱们在反序列化的时候,打印出来的就是Person [name=vae, age=0],整型数据默认值为 0 

 

问题2:序列化版本问题,在完成序列化操做后,因为项目的升级或修改,可能咱们会对序列化对象进行修改,好比增长某个字段,那么咱们在进行反序列化就会报错:

 

 

解决办法:在 JavaBean 对象中增长一个 serialVersionUID 字段,用来固定这个版本,不管咱们怎么修改,版本都是一致的,就能进行反序列化了

private static final long serialVersionUID = 8656128222714547171L;
相关文章
相关标签/搜索