首先,为抽象出一个序列化/反序列化通用服务,定义接口ISerializer.java,代码如下:
package ares.remoting.framework.serialization.serializer;
/**
* @author fuss created on 18/7/23.
* @version $Id$
*/
public interface ISerializer {
/**
* 序列化
*
* @param obj
* @param <T>
* @return
*/
public <T> byte[] serialize(T obj);
/**
* 反序列化
*
* @param data
* @param clazz
* @param <T>
* @return
*/
public <T> T deserialize(byte[] data, Class<T> clazz);
}
JDK提供了Java对象的序列化方式。Java的序列化主要通过对象输出流java.io.ObjectOutputStream与对象输入流java.io.ObjectInputStream来实现,其中被序列化的类需要实现java.io.Serializable接口,代码如下:
package ares.remoting.framework.serialization.serializer.impl;
import ares.remoting.framework.serialization.serializer.ISerializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* java默认序列化
*
* @author fuss created on 18/7/23.
* @version $Id$
*/
public class DefaultJavaSerializer implements ISerializer {
public <T> byte[] serialize(T obj) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(obj);
objectOutputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
return byteArrayOutputStream.toByteArray();
}
public <T> T deserialize(byte[] data, Class<T> clazz) {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
try {
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (T) objectInputStream.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
关于Java序列化还有如下知识:
1、序列化时,只对对象的状态进行保存,而不管对象的方法。
2、当一个父类实现序列化,子类自动实现序列化,不需要显示实现Serializable接口。
3、当一个对象的是咧变量引用其他对象,序列化该对象时也把引用对象进行序列化。
4、当某个字段被声明为transient后,默认序列化机制就会忽略该字段。
5、对于上述已被声明transient的字段,可以再类中添加私有方法writeObject()与readObject()两个方法来进行序列化。
JDK中提供了另一个序列化接口Externalizable,Externalizable继承于Serializable,当使用该接口时,序列化细节需要由程序员自主完成,适用于有特殊定制化需求的场景。
Java默认序列化机制的优缺点:
优点:
- Java语言自带,无需额外引入第三方依赖。
- 与Java语言有天然的最好的易用性与亲和性。
缺点:
- 只支持Java语言,不支持跨语言。
- Java默认序列化性能欠佳,序列化后产生的码流过大,对于引用过深的对象序列化易发生内存OOM异常。