首先,爲抽象出一個序列化/反序列化通用服務,定義接口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異常。