Java之路:对象序列化

一、对象序列化的基本概念

所谓的对象序列化(在某些书籍中也叫串行化),是指在内存之中保存的对象转化为二进制数据流的形式的一种操作。通过将对象序列化,可以方便地实现对象的传输及保存。

但是在Java之中并不是所有的类的对象都可以被序列化,如果一个类对象需要被序列化,则此类一定要实现java. io.Serializable接口。但是这个接口里面也没有定义任何的方法,所以此接口依然属于标识接口,表示一种能力。

在Java中提供有ObjectlnputStreamObjectOutputStream这两个类用于序列化对象的操作。这两个类是用于存储和读取对象的输入输出流类,不难想象,只要把对象中的所有成员变量都存储起来,就等于保存了这个对象,之后从保存的对象之中再将对象读取进来就可以继续使用此对象。

ObjectInputStream与ObjectOutputStream类,用于帮助开发者完成保存和读取对象成员变量取值的过程,但要求读写或存储的对象必须实现了Serializable接口,但Serializable接口中没有定义任何方法,仅仅被用做一种标记,以被编译器做特殊处理。如下范例所示。

【示例1】

package com.xy.io;

import java.io.Serializable;

public class Person implements Serializable {	
// Person实现了Serializable接口,所以此类定义的对象可被序列化
	private String name;
	private int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String toString() {
		return "姓名:" + this.name + ", 年龄:" + this.age;
	}
}

二、对象输出流——ObjectOutputStream

虽然类已经实现了Serializable接口,但是如果要想真正地实现具体的序列化操作,则用户可以使用ObjectOutputStream类完成,这个类继承结构如下。

java.lang.Object
|- java.io.OutputStream
|- java.io.ObjectOutputStream

由上述类的继承关系,可以发现ObjectOutputStream是OutputStream子类,因为对象序列化之后为二进制数据,所以只能够依靠字节流操作,同时在ObjectOutputStream类中定义了以下两个方法:

1)构造方法。public ObjectOutputStream(OutputStream out) throws IOException;
(2)输出对象:public final void writeObject(Object obj) throws IOException;

ObjectOutputStream 用于将对象序列化,并保存。其操作如下。

OutputStream outputFile = new FileOutputStream(new File(“SerializedPerson”));
ObjectOutputStream cout = new ObjectOutputStream(outputFile);
cout.writeObject(new Person("张三",25));
cout.close();

ObjectOutputStream 接收一个OutputStream对象用于保存待序列化的对象。然后cout调用writeObject 方法保存对象。

三、对象输入流——ObjectInputStream

如果希望将已被序列化的对象再反序列化回来,则就可以通过ObjectInputStream类完成,它用于读取将序列化的对象。此类继承关系如下。

java.lang.Object
|- java.io.InputStream
|- java.io.ObjectInputStream

对于ObjectInputStream类之中主要使用的两个方法如下。

1)构造方法。public ObjectInputStream(InputStream in) throws IOException;
(1)对象输入:public final Object readObject() throws IOException, ClassNotFoundException;

实现对象的反序列化(读取对象)操作如下。

InputStream inputFile = new FileInputStream(new File(“SerializedPerson”));
ObjectInputStream cin = new ObjectInputStream(inputFile);
Person p = (Person) cin.readObject();
System.out.println(p);

ObjectInputStream接收一个InputStream对象用于保存待序列化的对象。然后cin调用readObject方法读取序列化后的对象。

四、反序列化的基本概念

反序列化实际上就是使用ObjectInputStream 类创建对象将序列化后的对象读取出来,继续使用此对象。下面的例子结合ObjectInputStream 和OutputStream演示如何序列化对象和反序列化对象。
【示例2】

package com.xy.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;

public class SerializableDemo {
	public static void main(String[] args) throws Exception {
		File f = new File("SerializedPerson");
		serialize(f);
		deserialize(f);
	}
	
	// 序列化对象方法,将对象保存在文件之中
	public static void serialize(File f) throws Exception {
		OutputStream outputFile = new FileOutputStream(f);
		ObjectOutputStream cout = new ObjectOutputStream(outputFile);
		cout.writeObject(new Person("张三", 25));
		cout.close();
	}
	
	// 反序列化对象方法,从文件中读取已经保存的对象
	public static void deserialize(File f) throws Exception {
		InputStream inputFile = new FileInputStream(f);
		ObjectInputStream cin = new ObjectInputStream(inputFile);
		Person p = (Person)cin.readObject();
		System.out.println(p);
		cin.close();
	}
}

class Person implements Serializable {
	private String name;
	private int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String toString() {
		return "姓名:" + this.name + ", 年龄:" + this.age;
	}
}

【结果】
在这里插入图片描述

五、transient关键字

在默认情况下,当一个类对象序列化时,会将这个类中的全部属性都保存下来,如果不希望类中的某个属性被序列化(或某些属性不希望被保存,则可以在声明属性之前加上transient关键字。下面的代码修改自 【示例2】 ,在声明属性时,前面多加了一个transient关键字。

private transient String name;
private transient int age;

再次运行 【示例2】 程序时,其输出结果如下图所示。
在这里插入图片描述
从输出结果可以看到,Person类中的两个属性并没有被保存下来,输出时,是直接输出了这两个属性的默认值null和0。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值