对象在java中是以堆的方式存储。有时候需要复制对象或者存储对象,而不是对象的引用,这时候就需要用的对象的序列化和反序列化。
1.序列化
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
很详细的博客。
简单的来说大概有几点注意事项:
- 对象要实现了Serializable 接口
- 如果序列化和反序列化的serialVersionUID不同则反序列化失败,因为java是通过这个来进行序列化验证的。因此最好还是要定义serialVersionUID
- 序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量
- Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null
- 一个子类实现了 Serializable 接口,它的父类都没有实现 Serializable 接口,序列化该子类对象,然后反序列化后输出父类定义的某变量的数值,该变量数值与序列化时的数值不同。反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。
2.实例
1 /** 2 * Copyright © 2012-2014 JeeSite All rights reserved. 3 */ 4 package com.thinkgem.jeesite.common.utils; 5 6 import java.io.ByteArrayInputStream; 7 import java.io.ByteArrayOutputStream; 8 import java.io.ObjectInputStream; 9 import java.io.ObjectOutputStream;10 import java.lang.reflect.Method;11 12 import org.apache.commons.lang3.StringUtils;13 14 /**15 * 对象操作工具类, 继承org.apache.commons.lang3.ObjectUtils类16 * @author ThinkGem17 * @version 2014-6-2918 */19 public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {20 21 /**22 * 注解到对象复制,只复制能匹配上的方法。23 * @param annotation24 * @param object25 */26 public static void annotationToObject(Object annotation, Object object){27 if (annotation != null){28 Class annotationClass = annotation.getClass();29 Class objectClass = object.getClass();30 for (Method m : objectClass.getMethods()){31 if (StringUtils.startsWith(m.getName(), "set")){32 try {33 String s = StringUtils.uncapitalize(StringUtils.substring(m.getName(), 3));34 Object obj = annotationClass.getMethod(s).invoke(annotation);35 if (obj != null && !"".equals(obj.toString())){36 if (object == null){37 object = objectClass.newInstance();38 }39 m.invoke(object, obj);40 }41 } catch (Exception e) {42 // 忽略所有设置失败方法43 }44 }45 }46 }47 }48 49 /**50 * 序列化对象51 * @param object52 * @return53 */54 public static byte[] serialize(Object object) {55 ObjectOutputStream oos = null;56 ByteArrayOutputStream baos = null;57 try {58 if (object != null){59 baos = new ByteArrayOutputStream();60 oos = new ObjectOutputStream(baos);61 oos.writeObject(object);62 return baos.toByteArray();63 }64 } catch (Exception e) {65 e.printStackTrace();66 }67 return null;68 }69 70 /**71 * 反序列化对象72 * @param bytes73 * @return74 */75 public static Object unserialize(byte[] bytes) {76 ByteArrayInputStream bais = null;77 try {78 if (bytes != null && bytes.length > 0){79 bais = new ByteArrayInputStream(bytes);80 ObjectInputStream ois = new ObjectInputStream(bais);81 return ois.readObject();82 }83 } catch (Exception e) {84 e.printStackTrace();85 }86 return null;87 }88 }
java.io.ObjectOutputStream:表示对象输出流
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream:表示对象输入流
它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。
本示例中,将对象序列化为byte数组,首先创造一个ByteArrayOutputStream字节数组输出流,表示输出。然后使用ObjectOutputStream(字节数组输出流)来构造一个对象输出流,表示将对象输出到字节数组输出流中。最后通过 oos.writeObject(object);将object写入字节数组输出流,再转换为字节数组。反序列则相反。
本文转自Ryan.Miao博客园博客,原文链接:http://www.cnblogs.com/woshimrf/p/5212639.html,如需转载请自行联系原作者