java之序列化学习笔记(高效java之序列化)

序列化

 * 序列化与反序列化的学习笔记 测试 
 * ObjectOutputStream--序列化(将对象编码为字节流) 
 * ObjectInputStream--反序列化(从字节流中重构对象/用字节流转为唯一参数的构造器)
 * Serializable-->为标记接口,实现之,则具有可序列功能
 * 序列化形式
 * 		-->会成为导出API的一部分
 * 		-->默认的序列化形式(描述对象内部所包含的数据,以及每一个可以从这个对象到达的其他对象的内部数据)
 * 		-->理想的序列化形式(只表示对象的逻辑结构)
 * 序列版本UID-->如果未显示指定,则在运行此类时,根据此类的名称、实现接口名称、所有公有的和受保护的成员的名称所生成
 * 
 * 默认将当前类的非静态和非瞬态类写入
 * s.defaultWriteObject()
 * 从流中读取当前类的非静态和非瞬态的状态
 * s.defaultReadObject()
 * 
 * 控制序列化写
 * private void writeObject(ObjectOutputStream s)
 * 控制序列化写替换
 * private Object writeReplace()
 * 控制序列化读
 * private void readObject(ObjectInputStream s)
 * 控制序列化读替换
 * private  Object readResolve()


测试代码

/**
 * 
 */
package com.undergrowth.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Locale;

import org.junit.Test;

/**
 * 序列化与反序列化的学习笔记 测试 
 * ObjectOutputStream--序列化(将对象编码为字节流) 
 * ObjectInputStream--反序列化(从字节流中重构对象/用字节流转为唯一参数的构造器)
 * Serializable-->为标记接口,实现之,则具有可序列功能
 * 序列化形式
 * 		-->会成为导出API的一部分
 * 		-->默认的序列化形式(描述对象内部所包含的数据,以及每一个可以从这个对象到达的其他对象的内部数据)
 * 		-->理想的序列化形式(只表示对象的逻辑结构)
 * 序列版本UID-->如果未显示指定,则在运行此类时,根据此类的名称、实现接口名称、所有公有的和受保护的成员的名称所生成
 * 
 * 默认将当前类的非静态和非瞬态类写入
 * s.defaultWriteObject()
 * 从流中读取当前类的非静态和非瞬态的状态
 * s.defaultReadObject()
 * 
 * 控制序列化写
 * private void writeObject(ObjectOutputStream s)
 * 控制序列化写替换
 * private Object writeReplace()
 * 控制序列化读
 * private void readObject(ObjectInputStream s)
 * 控制序列化读替换
 * private  Object readResolve()
 * @author Administrator
 * 
 */
public class SerializableLearn {

	/**
	 * 
	 */
	public SerializableLearn() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * 输出类库中自带的类-->已经序列化的 输出到控制台
	 */
	@Test
	public void testObjectOutStreamSystem() {
		// 输出到控制台
		try {
			oStream = new ObjectOutputStream(System.out);
			oStream.writeObject(Calendar.getInstance());
			oStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			closeOutStream(oStream);
		}
	}

	/**
	 * 输出类库中自带的类-->已经序列化的 输出到文件中
	 */
	@Test
	public void testObjectOutStreamFile() {
		// 输出到文件中
		outPutFileStream(Calendar.getInstance());
	}

	/**
	 * 将对象写入到输出流中
	 * @param object
	 */
	private void outPutFileStream(Object object) {
		try {
			isFileExist(filePath);
			filePath = new File(filePath, getFileName());
			oStream = new ObjectOutputStream(new FileOutputStream(filePath));
			oStream.writeObject(object);
			oStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			closeOutStream(oStream);
		}
	}

	
	
	
	/**
	 * 读取系统类库序列化的类,进行反序列化
	 */
	@Test
	public void testObjectInputStreamFile(){
		//从文件中读入
		Calendar calendar=(Calendar) inPutFileStream();
		 System.out.println(calendar.getTime().toString());
	}

	/**
	 * 读入文件流
	 */
	private Object inPutFileStream() {
		Object object=null;
		try {
			isFileExist(filePath);
			filePath = new File(filePath, getFileName());
			oisStream = new ObjectInputStream(new FileInputStream(filePath));
		    object=oisStream.readObject();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			closeInputStream(oisStream);
		}
		return object;
	}
	
	/**
	 * 测试自定义的序列化类-->对序列化进行更多的控制
	 */
	@Test
	public void testObjectOutputStreamCustom(){
		CustomSerializableClass customSerializableClass=new CustomSerializableClass("自定义序列化", Calendar.getInstance());
		outPutFileStream(customSerializableClass);
	}
	
	/**
	 * 测试自定义的反序列化类--->对反序列化进行更多的控制
	 */
	@Test
	public void testObjectInputStreamCustom(){
		CustomSerializableClass customSerializableClass=(CustomSerializableClass) inPutFileStream();
		System.out.println(customSerializableClass);
	}
	
	/**
	 * 测试自定义的序列化类-->使用序列代理进行控制序列化
	 */
	@Test
	public void testObjectOutputStreamCustomProxy(){
		CustomSerializableProxyClass customSerializableClass=new CustomSerializableProxyClass("自定义序列化", Calendar.getInstance());
		outPutFileStream(customSerializableClass);
	}
	
	/**
	 * 测试自定义的反序列化类--->使用序列代理进行控制反序列化
	 */
	@Test
	public void testObjectInputStreamCustomProxy(){
		CustomSerializableProxyClass customSerializableClass=(CustomSerializableProxyClass) inPutFileStream();
		System.out.println(customSerializableClass);
	}
	
	/**
	 * 未实现Serializable接口 尝试输出 则会报错
	 * java.io.NotSerializableException: com.undergrowth.io.CustomNoSerializableClass
	 */
	@Test
	public void testObjectNoSerializable(){
		CustomNoSerializableClass cuNo=new CustomNoSerializableClass("自定义序列化");
		outPutFileStream(cuNo);
	}
	
	
	/**
	 * 关闭输入流
	 * @param oisStream2
	 */
	private void closeInputStream(ObjectInputStream oisStream2) {
		// TODO Auto-generated method stub
		if (oisStream2 != null) {
			try {
				oisStream2.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}



	// 输出路径
	String pathname = "d:\\log\\";
	String fileNameSuffix=".txt";
	File filePath = new File(pathname);
	ObjectOutputStream oStream = null;
	ObjectInputStream oisStream=null;
	/**
	 * 关闭输出流
	 * 
	 * @param osStream2
	 */
	private void closeOutStream(OutputStream osStream2) {
		// TODO Auto-generated method stub
		if (osStream2 != null) {
			try {
				osStream2.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 判断文件是否存在
	 * 
	 * @param filePath2
	 */
	private void isFileExist(File filePath2) {
		// TODO Auto-generated method stub
		if (!filePath2.exists())
			filePath2.mkdir();
	}

	/**
	 * 获取文件名
	 * 
	 * @return
	 */
	private String getFileName() {
		// TODO Auto-generated method stub
		Calendar calendar = Calendar.getInstance(Locale.CHINA);
		String fileName = calendar.get(Calendar.YEAR) + "_"
				+ (calendar.get(Calendar.MONTH) + 1) + "_"
				+ calendar.get(Calendar.DAY_OF_MONTH) + "_"
				+ SerializableLearn.class.getSimpleName() + fileNameSuffix;
		return fileName;
	}
}


自定义的序列化类

/**
 * 
 */
package com.undergrowth.io;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Calendar;

/**
 * 自定义的序列化类
 * @author Administrator
 *
 */
public class CustomSerializableClass implements Serializable {

	private static final int NUM=10;
	private String name;
	private volatile Calendar calendar;
	//transient关键字进行修饰 表示此字段会从默认的序列化形式中省略
	private transient Double numDouble=100.0;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 
	 */
	public CustomSerializableClass() {
		// TODO Auto-generated constructor stub
	}

	public CustomSerializableClass(String name, Calendar calendar) {
		super();
		this.name = name;
		this.calendar = calendar;
	}

	@Override
	public String toString() {
		return "CustomSerializableClass [name=" + name + ", calendar="
				+ calendar.getTime().toString() +",NUM="+NUM+",numDouble="+numDouble+"]";
	}
	
	/**
	 * 控制序列化过程
	 * @param s
	 */
	private void writeObject(ObjectOutputStream s){
		//默认将当前类的非静态和非瞬态类写入
		try {
			s.defaultWriteObject();
			//将瞬态的状态写入 不然默认的序列化形式 是不写入的 进行反序列化的时候 会得到null
			s.writeDouble(numDouble);
			System.out.println("序列化成功");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	
	/**
	 * 控制反序列化过程
	 * @param s
	 */
	private void readObject(ObjectInputStream s){
		try {
			//从流中读取当前类的非静态和非瞬态的状态
			s.defaultReadObject();
			numDouble=s.readDouble();
			System.out.println("反序列化成功");
		} catch (ClassNotFoundException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	/**
	 * 在反序列化的时候 替换其反序列化的对象
	 * @return
	 */
	private  Object readResolve(){
		return new CustomSerializableClass("替换过后的反序列化值",Calendar.getInstance());
		
	}
	
	

}

自定义的序列化代理类

/**
 * 
 */
package com.undergrowth.io;

import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Calendar;

/**
 * 自定义的序列化类
 *  使用序列化代理 控制序列化
 * @author Administrator
 *
 */
public class CustomSerializableProxyClass implements Serializable {

	private static final int NUM=10;
	private String name;
	private volatile Calendar calendar;
	//transient关键字进行修饰 表示此字段会从默认的序列化形式中省略
	private transient Double numDouble=100.0;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 
	 */
	public CustomSerializableProxyClass() {
		// TODO Auto-generated constructor stub
	}

	public CustomSerializableProxyClass(String name, Calendar calendar) {
		super();
		this.name = name;
		this.calendar = calendar;
	}

	@Override
	public String toString() {
		return "CustomSerializableClass [name=" + name + ", calendar="
				+ calendar.getTime().toString() +",NUM="+NUM+",numDouble="+numDouble+"]";
	}
	
	/**
	 * 使用序列化代理序列化此类
	 * @return
	 */
	private Object writeReplace(){
		return new SerialzlizableProxy(this);
	}
	
	/**
	 * 使用序列化代理
	 * 序列化谁,反序列化时就调用谁的方法
	 *   对外围类进行序列化时,使用序列化代理进行序列化
	 *   对外围类进行反序列化时,使用代理类返回外围类
	 * @author Administrator
	 *
	 */
	private static class SerialzlizableProxy implements Serializable{

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private String name;
		
		
		public SerialzlizableProxy(
				CustomSerializableProxyClass customSerializableClass) {
			// TODO Auto-generated constructor stub
			this.name=customSerializableClass.name;
		}
		
		private Object readResolve(){
			System.out.println("代理类进行反序列化-->"+name);
			return new CustomSerializableProxyClass("使用序列化代理,替换过后的反序列化值",Calendar.getInstance());
		}
	}
	
	/**
	 * 防止从外围类进行调用
	 * @param s
	 * @throws InvalidObjectException
	 */
	private void readObject(ObjectInputStream s) throws InvalidObjectException{
		throw new InvalidObjectException("使用序列化代理返回");
	}

}

未序列化类

package com.undergrowth.io;

/**
 * 未实现Serializable接口  测试使用
 * @author Administrator
 *
 */
public class CustomNoSerializableClass {

	private String name;
	
	public CustomNoSerializableClass(String name) {
		// TODO Auto-generated constructor stub
		this.name=name;
	}

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值