序列化与反序列化

1、序列化概述

在开发中,经常需要将对象的信息保存到磁盘中,便于以后检索。序列化提供了轻松实现这个目标的快捷方法。

简单的说,序列化就是将对象的状态存储到特定存储介质的过程,也就是将对象状态转换为可保存或传输格式的过程。在序列化过程中,会将对象的公有成员,私有成员包括类名,转换为字节流,然后再把字节流写入数据流,存储到存储介质中,这里说的存储介质通常指的是文件。

使用序列化的意义在于将Java对象序列化后,可以将其转换为字节序列,这些字节序列可以被保存到磁盘中,也可以借助网络进行传输,同时序列化后的对象保存的是二进制状态,这样实现了平台无关性,即可以把Windows操作系统中实现序列化的一个对象,传输到UNIX操作系统的机器上,通过反序列化得到对象,而无需担心数据因为平台问题显示异常。

2、使用序列化保存对象信息

序列化机制允许将实现序列化的的Java对象转换为字节序列,这个过程需要借助于IO流来实现。Java 中,只有实现了java.io.Serializable接口的类的对象才能被序列化,Serializable表示可串行的,可序列化的,所以,对象序列化在某些文献上也被称为串行化。JDK类库中有些类,如String类,包装类和Date类等都实现了Serializable接口。

对象序列化的步骤:

a、创建一个对象输出流(ObjectOutputStream),它可以包装一个其他类型的输出流,如文件输出流(FileOutputStream)。

ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D:\\myTest\\Test.txt"));

b、通过对象输出流的writeObject()方法写对象,也就是输出可序列化对象。

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;

public class WriteObjectTest {

	public static void main(String[] args) throws FileNotFoundException, IOException {
		//本代码直接抛出异常,没有处理
		
		
		Date date = new Date();
		ObjectOutputStream oos = new ObjectOutputStream(
				new FileOutputStream("C:\\Users\\zhangwendi\\Desktop\\Test.txt"));
		oos.writeObject(date);

		if (oos != null)
			oos.close();
	}
}

3、使用反序列化获取对象信息

序列化是将对象的状态信息保存到存储介质中,

反序列化是从特定的存储介质中将数据重新构建对象的过程。

通过反序列化,可以将存储在文件上的对象信息读取,然后重新构建为对象。

步骤:

a、创建一个对象输入流(ObjectInputStream),它可以包装一个其他类型的输入流,如文件输入流FileInputStream

b、通过对象输入流的readObject()方法读取对象,该方法返回一个Object类型的对象,如果程序知道该Java对象的类型,则可以将该对象强制转换为其真实的类型。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ReadObjectTest {

	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		// 本代码直接抛出异常,没有处理

		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\zhangwendi\\Desktop\\Test.txt"));
		Date d = (Date) (ois.readObject());
		SimpleDateFormat dateformat = new SimpleDateFormat("YYYY年MM月dd日HH:mm:ss");
		System.out.println(dateformat.format(d));

		System.out.println(d);

		ois.close();

	}
}

通常,对象中的所有属性都会被序列化,但是对于一些比较敏感的信息,如用户的密码,一旦序列化后,人们完全可以通过读取文件或拦截网络传输数据的方式,获得这些信息。因此,出于对安全的考虑,某些属性应该被限制序列化。解决得方法是,使用transient修饰。

注意:

a、如果向文件中使用序列化机制写入多个对象,那么反序列化恢复对象时,必须按照写入的顺序读取。

b、如果一个可序列化的类,有多个父类(包括直接或间接父类),则这些父类要么也是可序列化的,要么有无参数的构造器。否则会抛出异常。

4、对象引用的序列化

如果一个类的成员包括其他类的对象时,如班级类中包含学生类型的对象,那么当要序列化班级对象时,则必须保证班级类和学生类都是可序列化的。即当需要序列化某个特定对象,那么它的各个成员对象也必须是可序列化的。

序列化的算法规则如下:

所有保存到磁盘中的对象都有一个序列号。

当程序试图序列化一个对象时,将会检查是否已经被序列化,只有序列化后的对象才能被转换为字节序列输出。

如果对象已经被序列化,则程序直接输出一个序列化编号,而不再重新序列化。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值