Java高级对象序列化

对象序列化概述

通过使用ObjectInputStream和ObjectOutputStream类保存和读取 对象的机制叫做序列化机制
对象(Object)序列化是指将对象转换为字节码序列的过程
反序列化则是根据字节码序列恢复对象的过程

序列化一般用于以下场景:

  • 永久性保存对象,保存对象的字节序列到本地文件中
  • 通过序列化对象在网络中传递对象
  • 通过序列化在进程间传递对象

支持序列化的接口和类

  • ObjectOutputStream : 提供序列化对象并把其写入流的方法
  • ObjectInputStream : 读取流并反序列化对象
  • Serializable接口:一个对象想要被序列化,那么它的类就要实现 此接口,这个对象的所有属性(包括private属性、包括其引用的对象)都可以被序列化和反序列化来保存、传递。
  • Externalizable接口 : 他是Serializable接口的子类,有时我们不希望序列化那么多,可以使用这个接口,这个接口的writeExternal()和readExternal()方法可以指定序列化哪些属性; 但是如果你只想隐藏一个属性,比如用户对象user的密码pwd,如果使用Externalizable,并除了pwd之外的每个属性都写在writeExternal()方法里,这样显得麻烦,可以使用Serializable接口,并在要隐藏的属性pwd前面加上transient就可以实现了。

序列化的过程,是将任何实现了Serializable接口或 Externalizable接口的对象通过ObjectOutputStream类 提供的相应 方法转换为连续的字节数据,这些数据以后仍可通过 ObjectInputStream类 提供的相应方法被还原为原来的对象状态, 这样就可以将对象完成的保存在本地文件中,或在网络和进程间传递

实现Serializable接口的Demo

写一个student类实现Serializable接口

package com.neuedu.chapter03._文件与流_序列化;
import java.io.Serializable;
public class Student implements Serializable {
	private String name;  //私有属性
	private int age; 
	/**
	 * 
	 */
	public Student() {
		super();//默认构造函数
		// TODO Auto-generated constructor stub
	}
	/**
	 * @param name
	 * @param age
	 * 给name、age赋值的构造函数
	 */
	public Student(String name, int age) {  //有参构造函数
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {  //成员变量的get和set方法
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

写一个实现序列化和反序列化的类(ObjectInputStream_ObjectOuputStream_Implements_Serializable)

package com.neuedu.chapter03._文件与流_序列化;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ObjectInputStream_ObjectOuputStream_Implements_Serializable {
	//序列化方法
	public static void serializanle() {
		ObjectOutputStream output = null;		
		try {
			//实例化student类
			Student stu = new Student("大刘",19);

			//实例化存放字节码的对象
			FileOutputStream out = new FileOutputStream("file/student.txt");
			//实例化序列化对象
			output = new ObjectOutputStream(out);
			//进行序列化
			output.writeObject(stu);			
			//强制刷新
			output.flush();
			System.out.println("序列化对象成功!");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if(output != null) {
					output.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}		
	}
	//反序列化方法
	public static void deSerializable() {
		ObjectInputStream input = null;
		try {
			//实例化对象,取到序列化对象的字节码存放文件
			FileInputStream in = new FileInputStream("file/student.txt");
			//创建反实例化对象
			input = new ObjectInputStream(in);
			//反序列化为Student对象
			Student stu = (Student)input.readObject();
			//打印反序列化出来的对象
			System.out.println("反序列化出来的信息:  "+stu.toString());						
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	public static void main(String[] args) {
		serializanle();//序列化
		deSerializable(); //反序列化
	}
}

实现Externalizable接口的Demo

写一个类实现Externalizable接口

package com.neuedu.chapter03._文件与流_序列化;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class Student_E implements Externalizable{
	private int cno;  //学号
	private String cname;
	private int psd;  //学号密码
	public Student_E() {
		psd = 123456;  //g给学设个密码赋值
	}
	/**
	 * @param cno
	 * @param cname
	 */
	public Student_E(int cno, String cname) {  //无密码参数的构造函数
		super();
		this.cno = cno;
		this.cname = cname;
	}	
	public int getCno() {
		return cno;
	}
	public void setCno(int cno) {
		this.cno = cno;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	public int getPsd() {
		return psd;
	}
	public void setPsd(int psd) {
		this.psd = psd;
	}
	//必须覆盖(重写)父类的序列化和反序列化的两个方法
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		// TODO Auto-generated method stub
		//指定序列化时写入的属性,这不写学号的密码
		out.writeObject(cno);
		out.writeObject(cname);
	}
	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		// TODO Auto-generated method stub
		cno = (int)in.readObject();
		cname = (String)in.readObject();
	}
}

写一个类实现序列化和反序列化的类

package com.neuedu.chapter03._文件与流_序列化;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectInputStream_ObjectOuputStream_Implements_Externalizable {
	public static void externalizable() {
		ObjectOutputStream output = null;
		
		try {
			//实例化student类
			Student_E stu = new Student_E(1908,"小刘");
			//实例化存放字节码的对象
			FileOutputStream out = new FileOutputStream("file/student.txt");
			output = new ObjectOutputStream(out);
			//进行序列化
			output.writeObject(stu);
			//强制刷新
			output.flush();
			System.out.println("序列化对象成功!");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//反序列化
		public static void deSerializable() {
			ObjectInputStream input = null;
			try {
				//实例化对象,取到序列化对象的字节码存放文件
				FileInputStream in = new FileInputStream("file/student.txt");
				//创建反实例化对象
				input = new ObjectInputStream(in);
				//反序列化为Student对象
				Student_E stu = (Student_E)input.readObject();
				//打印反序列化出来的对象
				System.out.println("反序列化出来的信息:  "+stu.toString());						
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		public static void main(String[] args) {
			externalizable();
			deSerializable();
		}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_mo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值