Java的序列化機制原理分析,我們查看下ObjectOutputStream的writeObject方法
- //final方法,不允許子類覆蓋
- public final void writeObject(Object obj) throws IOException {
- if (enableOverride) { //如果開啟允許序列化被重寫
- writeObjectOverride(obj); //調用子類的序列化重寫方法
- return;
- }
- try {
- writeObject0(obj, false);//調用默認的序列化過程
- } catch (IOException ex) {
- if (depth == 0) {
- writeFatalException(ex);
- }
- throw ex;
- }
- }
如果要自定義這個序列化過程,則可以寫一個子類,集成ObjectOutputStream,然後覆蓋其兩個方法
- protected ObjectOutputStream() throws IOException, SecurityException {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
- }
- bout = null;
- handles = null;
- subs = null;
- enableOverride = true;
- debugInfoStack = null;
- }
- protected void writeObjectOverride(Object obj) throws IOException {
- }
我們再看下具體的writeObject0方法:
- private void writeObject0(Object obj, boolean unshared)
- throws IOException
- {
- boolean oldMode = bout.setBlockDataMode(false);
- depth++;
- try {
- // 先對obj實例的類信息進行序列化,
- int h;
- if ((obj = subs.lookup(obj)) == null) {
- writeNull();
- return;
- } else if (!unshared && (h = handles.lookup(obj)) != -1) {//可以自定義class類信息的序列化handler
- writeHandle(h);
- return;
- } else if (obj instanceof Class) { //類信息序列化
- writeClass((Class) obj, unshared);
- return;
- } else if (obj instanceof ObjectStreamClass) { //類信息序列化,此時還包括serialVersionUID
- writeClassDesc((ObjectStreamClass) obj, unshared);
- return;
- }
-
- // check for replacement object
- //這裡還可以對序列化的類進行替換序列化
- Object orig = obj;
- Class cl = obj.getClass();
- ObjectStreamClass desc;
- for (;;) {
- // REMIND: skip this check for strings/arrays?
- Class repCl;
- desc = ObjectStreamClass.lookup(cl, true);
- if (!desc.hasWriteReplaceMethod() ||
- (obj = desc.invokeWriteReplace(obj)) == null ||
- (repCl = obj.getClass()) == cl)
- {
- break;
- }
- cl = repCl;
- }
- if (enableReplace) {
- Object rep = replaceObject(obj);
- if (rep != obj && rep != null) {
- cl = rep.getClass();
- desc = ObjectStreamClass.lookup(cl, true);
- }
- obj = rep;
- }
-
- // if object replaced, run through original checks a second time
- //如果類信息被替換過,則需要進行第二次處理
- if (obj != orig) {
- subs.assign(orig, obj);
- if (obj == null) {
- writeNull();
- return;
- } else if (!unshared && (h = handles.lookup(obj)) != -1) {
- writeHandle(h);
- return;
- } else if (obj instanceof Class) {
- writeClass((Class) obj, unshared);
- return;
- } else if (obj instanceof ObjectStreamClass) {
- writeClassDesc((ObjectStreamClass) obj, unshared);
- return;
- }
- }
-
- // 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) { //我們的bean需要實現Serializable接口,才能進行序列化
- writeOrdinaryObject(obj, desc, unshared);
- } else {
- if (extendedDebugInfo) {
- throw new NotSerializableException(
- cl.getName() + "\n" + debugInfoStack.toString());
- } else {
- throw new NotSerializableException(cl.getName());
- }
- }
- } finally {
- depth--;
- bout.setBlockDataMode(oldMode);
- }
- }