如何序列化和反序列化一个java对象

首先,什么是序列化?

序列化,目前已经得到大多数计算机语言的支持,Java也不例外,Java的序列化功能是作为I/O功能的一个子项,它的使用也是比较方便的;序列化,又称为“串化”,可以形象的把它理解为把java对象内存中的数据采编成一串二进制的数据,然后把这些数据存放在可以持久的数据存储设备,如磁盘。当需要还原这些数据的时候,再通过反序列化的过程,把对象又重新还原到内存中。

Java.io.SersionUID 是可以进行序列化的类的标志性接口,该接口本身没有任何需要实现的抽象方法,它仅仅是用来告诉JVM该类的对象可以进行序列化的,并且它的序列化ID又静态的SerialVersionUID 变量提供。

SerialVersionUID其实是一个静态的long常量,它的作用在序列化和反序列化的过程中,起到了辨别一个类的作用。在反序列化的时候,如果两个类的类名完全相同,就通过serialVersionUID来判断该类是否符合要求,如果不行,则抛出异常。

Java 的I/O提供了一对类作用对象的序列化和反序列化,主要包括ObjectOutputStream和ObjectInputStream。他们的用法与 字节流的用法相似,只不过此时处理的是对象,而不仅仅是字节数据了。

序列化本质上就是把对象内存中的数据按照一定的规则,变成一系列的字节数据,然后再把这些字节数据写入到流中。而反序列化的过程相反,先读取字节数据,然后再重新组装成Java对象。

所有进行序列化的类,都必须实现SerialIzable 接口,必要时还需要提供静态的常量serialVersionUID.

那么,如何序列化和反序列化一个Java对象?

Java既然对序列化和反序列化提供了支持,那么肯定就会提供相应的接口或类,以方便开发者使用,其中主要就体现为ObjectOutputStream类和ObjectInputStream类。只不过写入和读取的方法为:readObject()和writeObject()。以学生对象为例:

package com.leetch;
import java.io.*;
class Student implements Serializable{
	private static final long serialVersionUID=1L;
	private String nameString ;
	private int ageInt;
	public String getname(){
		return this.nameString;
	}
	public int getage(){
		return this.ageInt;
	}
	public void setName(String name){
		this.nameString = name;
	}
	public void setAge(int age){
		this.ageInt=age;
	}
}
public class SerialTest {
	public static void main(String[] args){
		Student student = new Student(); //创建一个学生对象
		student.setAge(20);
		student.setName("Yifan");
		try {
			ObjectOutputStream ooStream=new ObjectOutputStream(
					new FileOutputStream("F:/文件/my Documents/Coder/JAVA/File/obj.txt"));
			//创建一个对象输出流
			ooStream.writeObject(student); //把对象写入输出流,序列化,又称串化,把java对象内存中的数据采编成一串二进制的数据,然后把这些数据
										   //存放在可以持久的数据存储设备,如磁盘等
			ooStream.close();			  //关闭输出流 
			//创建一个对象输入流
			ObjectInputStream oisStream= new ObjectInputStream(
					new FileInputStream("F:/文件/my Documents/Coder/JAVA/File/obj.txt"));
			Object object = oisStream.readObject();   //读出已经序列化的对象
			Student stubac = (Student)object;         //进行类型转换
			//打印数据到控制台,检查序列化和反序列化是否成功?
			System.out.println("student name is"+stubac.getname());
			System.out.println("student age is"+stubac.getage());
			oisStream.close();
			
		} catch(Exception e){
			e.printStackTrace();
		}
	}
}


以上的实例中,student类只有两个成员变量,分别是int 和String类型,如果,需要序列化的类包含其他的引用类型的成员变量,则它所包含的这些类也是需要实现SerialIzable接口的,并且这样的关系是循环嵌套一直到底的。

对于对象的输出和输入,Java的I/O体系主要提供了ObjectOutputStream和ObjectInputStream两个类以供开发者使用,他们的基本使用思路有如下步骤:

(1),让需要序列化的类实现SerialIzable接口;

(2),在类中提供静态的long型常量serialVersionUID;

(3),如果是序列化的对象,则用一个输出流创建一个ObjectOutputStream对象,然后调用writeObject()方法;

(4),如果是反序列化的对象,首先使用一个输入流创建一个ObjectInputStream对象,然后调用readObject()方法;

(5),最后关闭输出输入流。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值