一、基础概念
Java 1.1 增添了一种有趣的特性,名为“对象序列化”( Object Serialization)。它面向那些实现了Serializable 接口的对象,可将它们转换成一系列字节,并可在以后完全恢复回原来的样子。
二、序列化过程
序列化原理请参考如下代码
import java.io.*;
/**
* 序列化工具
* Created by daiwei on 2018/1/31.
*/
public abstract class SerializationUtils {
/**
* Serialize the given object to a byte array.
* <P>
* 1.创建一个 ByteArrayOutputStream输出流baos
* 2.创建一个ObjectOutputStream输出流oos,并且以baos作为构造参数
* 3.将指定的对象写入 ObjectOutputStream
* 4.刷新该流的缓冲
* 5.以 byte 数组的形式返回此输出流的当前内容
* </P>
* @param object the object to serialize
* @return an array of bytes representing the object in a portable fashion
*/
public static byte[] serialize(Object object) {
if (object == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
}
catch (IOException ex) {
throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
}
return baos.toByteArray();
}
/**
* Deserialize the byte array into an object.
* <P>
* 1.创建一个ByteArrayInputStream输入流,并以bytes作为构造参数
* 2.创建一个ObjectInputStream输入流ois,并且以ByteArrayInputStream输入流作为构造参数
* 3.从 ObjectInputStream 读取对象。
* </P>
* @param bytes a serialized object
* @return the result of deserializing the bytes
*/
public static Object deserialize(byte[] bytes) {
if (bytes == null) {
return null;
}
try {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
return ois.readObject();
}
catch (IOException ex) {
throw new IllegalArgumentException("Failed to deserialize object", ex);
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException("Failed to deserialize object type", ex);
}
}
}
应用场景
1.对象持久化。
如写入磁盘,存储到redis等nosql数据库
2.远程方法调用”( RMI)
使本来存在于其他机器的对象可以表现出好象就在本地机器上的行为。将消息发给远程对象时,需要通过对
象序列化来传输参数和返回值。
框架基础
1.rpc
2.缓存
相关问题
1.为何Serializable设计成一个空接口
该Serializable接口仅是一个标记,没有方法,当执行序列化方法时,首先判断这个类是否实现了Serializable接口,如果没有实现则抛出异常等,实现了Serializable接口则继续往下执行序列化相关代码
jdk部分源码如下(在public final void writeObject(Object obj)方法里实现):
// remaining cases
if (obj instanceof String) {
writeString((String) obj, unshared);
} else if (cl.isArray()) {
writeArray(obj, desc, unshared);
} else if (obj instanceof Enum) {
writeEnum((Enum) obj, desc, unshared);
} else if (obj instanceof Serializable) { //判断对象是否实现了Serializable接口
writeOrdinaryObject(obj, desc, unshared);
} else {
if (extendedDebugInfo) {
throw new NotSerializableException(
cl.getName() + "\n" + debugInfoStack.toString());
} else {
throw new NotSerializableException(cl.getName());
}
}