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

来源:互联网 发布:德拉蒙德数据 编辑:程序博客网 时间:2024/05/17 06:12

序列化

 * 序列化与反序列化的学习笔记 测试  * 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}/** * 输出类库中自带的类-->已经序列化的 输出到控制台 */@Testpublic void testObjectOutStreamSystem() {// 输出到控制台try {oStream = new ObjectOutputStream(System.out);oStream.writeObject(Calendar.getInstance());oStream.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {closeOutStream(oStream);}}/** * 输出类库中自带的类-->已经序列化的 输出到文件中 */@Testpublic 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 blocke.printStackTrace();} finally {closeOutStream(oStream);}}/** * 读取系统类库序列化的类,进行反序列化 */@Testpublic 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 blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {closeInputStream(oisStream);}return object;}/** * 测试自定义的序列化类-->对序列化进行更多的控制 */@Testpublic void testObjectOutputStreamCustom(){CustomSerializableClass customSerializableClass=new CustomSerializableClass("自定义序列化", Calendar.getInstance());outPutFileStream(customSerializableClass);}/** * 测试自定义的反序列化类--->对反序列化进行更多的控制 */@Testpublic void testObjectInputStreamCustom(){CustomSerializableClass customSerializableClass=(CustomSerializableClass) inPutFileStream();System.out.println(customSerializableClass);}/** * 测试自定义的序列化类-->使用序列代理进行控制序列化 */@Testpublic void testObjectOutputStreamCustomProxy(){CustomSerializableProxyClass customSerializableClass=new CustomSerializableProxyClass("自定义序列化", Calendar.getInstance());outPutFileStream(customSerializableClass);}/** * 测试自定义的反序列化类--->使用序列代理进行控制反序列化 */@Testpublic void testObjectInputStreamCustomProxy(){CustomSerializableProxyClass customSerializableClass=(CustomSerializableProxyClass) inPutFileStream();System.out.println(customSerializableClass);}/** * 未实现Serializable接口 尝试输出 则会报错 * java.io.NotSerializableException: com.undergrowth.io.CustomNoSerializableClass */@Testpublic void testObjectNoSerializable(){CustomNoSerializableClass cuNo=new CustomNoSerializableClass("自定义序列化");outPutFileStream(cuNo);}/** * 关闭输入流 * @param oisStream2 */private void closeInputStream(ObjectInputStream oisStream2) {// TODO Auto-generated method stubif (oisStream2 != null) {try {oisStream2.close();} catch (IOException e) {// TODO Auto-generated catch blocke.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 stubif (osStream2 != null) {try {osStream2.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}/** * 判断文件是否存在 *  * @param filePath2 */private void isFileExist(File filePath2) {// TODO Auto-generated method stubif (!filePath2.exists())filePath2.mkdir();}/** * 获取文件名 *  * @return */private String getFileName() {// TODO Auto-generated method stubCalendar 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;}@Overridepublic String toString() {return "CustomSerializableClass [name=" + name + ", calendar="+ calendar.getTime().toString() +",NUM="+NUM+",numDouble="+numDouble+"]";}/** * 控制序列化过程 * @param s */private void writeObject(ObjectOutputStream s){//默认将当前类的非静态和非瞬态类写入try {s.defaultWriteObject();//将瞬态的状态写入 不然默认的序列化形式 是不写入的 进行反序列化的时候 会得到nulls.writeDouble(numDouble);System.out.println("序列化成功");} catch (IOException e) {// TODO Auto-generated catch blocke.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 blocke.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;}@Overridepublic 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 stubthis.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 stubthis.name=name;}}


0 0