Java序列化 writeObject流程

一、writeObject

        public final void writeObject(Object obj) throws IOException {
                if (this.enableOverride) {
                        this.writeObjectOverride(obj);
                } else {
                        try {
                                this.writeObject0(obj, false);
                        } catch (IOException var3) {
                                if (this.depth == 0) {
                                        this.writeFatalException(var3);
                                }

                                throw var3;
                        }
                }
        }

enableOverride通过调用不同的构造赋值,一般为false,调用writeObject0方法

二、writeObject0

        private void writeObject0(Object obj, boolean unshared) throws IOException {
                boolean oldMode = this.bout.setBlockDataMode(false);
                ++this.depth;

                try {
                    //使用subs.lookup查找对象obj,调用ReplaceTable的lookup
                        if ((obj = this.subs.lookup(obj)) == null) {
                                this.writeNull();
                                return;
                        }

                        int h;
                        //如果在数组中可以找到 调用writeHandle
                        if (!unshared && (h = this.handles.lookup(obj)) != -1) {
                                this.writeHandle(h);
                                return;
                        }
						//如果是Class对象
                        if (!(obj instanceof Class)) {
                        		//ObjectStreamClass 类用于描述序列化对象的类的信息
                        		//如果是ObjectStreamClass对象
                                if (obj instanceof ObjectStreamClass) {
                                        this.writeClassDesc((ObjectStreamClass)obj, unshared);
                                        return;
                                }

                                Object orig = obj;
                                Class<?> cl = obj.getClass();

                                while(true) {
                                        ObjectStreamClass desc = ObjectStreamClass.lookup(cl, true);
                                        Class repCl;
                                        //是否有writeReplace方法  反射调用writeReplace
                                        if (!desc.hasWriteReplaceMethod() || (obj = desc.invokeWriteReplace(obj)) == null || (repCl = obj.getClass()) == cl) {
                                                if (this.enableReplace) {
                                                        Object rep = this.replaceObject(obj);
                                                        if (rep != obj && rep != null) {
                                                                cl = rep.getClass();
                                                                //获取对象描述信息
                                                                desc = ObjectStreamClass.lookup(cl, true);
                                                        }

                                                        obj = rep;
                                                }

                                                if (obj != orig) {
                                                		//将替换对象存储到数组
                                                        this.subs.assign(orig, obj);
                                                        if (obj == null) {
                                                                this.writeNull();
                                                                return;
                                                        }

                                                        if (!unshared && (h = this.handles.lookup(obj)) != -1) {
                                                                this.writeHandle(h);
                                                                return;
                                                        }

                                                        if (obj instanceof Class) {
                                                                this.writeClass((Class)obj, unshared);
                                                                return;
                                                        }

                                                        if (obj instanceof ObjectStreamClass) {
                                                                this.writeClassDesc((ObjectStreamClass)obj, unshared);
                                                                return;
                                                        }
                                                }
												//如果是String对象
                                                if (obj instanceof String) {
                                                        this.writeString((String)obj, unshared);
                                                        return;
                                                } 
                                                //如果是数组
                                                else if (cl.isArray()) {
                                                        this.writeArray(obj, desc, unshared);
                                                        return;
                                                } else {//如果是枚举
                                                        if (obj instanceof Enum) {
                                                                this.writeEnum((Enum)obj, desc, unshared);
                                                        } else {
                                                                if (!(obj instanceof Serializable)) {
                                                                        if (extendedDebugInfo) {
                                                                                throw new NotSerializableException(cl.getName() + "\n" + this.debugInfoStack.toString());
                                                                        }

                                                                        throw new NotSerializableException(cl.getName());
                                                                }
																//将普通对象写入输出流
                                                                this.writeOrdinaryObject(obj, desc, unshared);
                                                        }

                                                        return;
                                                }
                                        }

                                        cl = repCl;
                                }
                        }
						//将类信息写入输出流
                        this.writeClass((Class)obj, unshared);
                } finally {
                        --this.depth;
                        this.bout.setBlockDataMode(oldMode);
                }

        }
        private static class ReplaceTable {
	                Object lookup(Object obj) {
	                	//在一个数组中查找有没有这个对象,返回下标,下标为-1就是没找到,返回obj
                        int index = this.htab.lookup(obj);
                        return index >= 0 ? this.reps[index] : obj;
                }        
		}
		        private static class HandleTable {
		             int lookup(Object obj) {
                        if (this.size == 0) {
                                return -1;
                        } else {
                                int index = this.hash(obj) % this.spine.length;

                                for(int i = this.spine[index]; i >= 0; i = this.next[i]) {
                                        if (this.objs[i] == obj) {
                                                return i;
                                        }
                                }

                                return -1;
                        }
                }
		        }

三、writeOrdinaryObject

        private void writeOrdinaryObject(Object obj, ObjectStreamClass desc, boolean unshared) throws IOException {
                if (extendedDebugInfo) {
                        this.debugInfoStack.push((this.depth == 1 ? "root " : "") + "object (class \"" + obj.getClass().getName() + "\", " + obj.toString() + ")");
                }

                try {
                        desc.checkSerialize();
                        this.bout.writeByte(115);
                        this.writeClassDesc(desc, false);
                        this.handles.assign(unshared ? null : obj);
                        if (desc.isRecord()) {
                                this.writeRecordData(obj, desc);
                        } else if (desc.isExternalizable() && !desc.isProxy()) {
                        //如果实现Externalizable接口
                                this.writeExternalData((Externalizable)obj);
                        } else {
                        //如果实现Serializable接口
                                this.writeSerialData(obj, desc);
                        }
                } finally {
                        if (extendedDebugInfo) {
                                this.debugInfoStack.pop();
                        }

                }

        }

四、writeSerialData

        private void writeSerialData(Object obj, ObjectStreamClass desc) throws IOException {
                ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();

                for(int i = 0; i < slots.length; ++i) {
                        ObjectStreamClass slotDesc = slots[i].desc;
                        //目标类是否有writeObject方法
                        if (slotDesc.hasWriteObjectMethod()) {
                                PutFieldImpl oldPut = this.curPut;
                                this.curPut = null;
                                SerialCallbackContext oldContext = this.curContext;
                                if (extendedDebugInfo) {
                                        this.debugInfoStack.push("custom writeObject data (class \"" + slotDesc.getName() + "\")");
                                }

                                try {
                                        this.curContext = new SerialCallbackContext(obj, slotDesc);
                                        this.bout.setBlockDataMode(true);
                                        //调用目标类的writeObject
                                        slotDesc.invokeWriteObject(obj, this);
                                        this.bout.setBlockDataMode(false);
                                        this.bout.writeByte(120);
                                } finally {
                                        this.curContext.setUsed();
                                        this.curContext = oldContext;
                                        if (extendedDebugInfo) {
                                                this.debugInfoStack.pop();
                                        }

                                }

                                this.curPut = oldPut;
                        } else {
                        		//目标类没有实现writeObject,调用此方法
                                this.defaultWriteFields(obj, slotDesc);
                        }
                }

        }

五、defaultWriteFields

		//将对象的字段写入输出流
        private void defaultWriteFields(Object obj, ObjectStreamClass desc) throws IOException {
                Class<?> cl = desc.forClass();
                if (cl != null && obj != null && !cl.isInstance(obj)) {
                        throw new ClassCastException();
                } else {
                        desc.checkDefaultSerialize();
                        int primDataSize = desc.getPrimDataSize();
                        if (primDataSize > 0) {
                                if (this.primVals == null || this.primVals.length < primDataSize) {
                                        this.primVals = new byte[primDataSize];
                                }
								//写入基本数据类型
                                desc.getPrimFieldValues(obj, this.primVals);
                                this.bout.write(this.primVals, 0, primDataSize, false);
                        }

                        int numObjFields = desc.getNumObjFields();
                        if (numObjFields > 0) {
                                ObjectStreamField[] fields = desc.getFields(false);
                                Object[] objVals = new Object[numObjFields];
                                int numPrimFields = fields.length - objVals.length;
                                desc.getObjFieldValues(obj, objVals);

                                for(int i = 0; i < objVals.length; ++i) {
                                        if (extendedDebugInfo) {
                                                this.debugInfoStack.push("field (class \"" + desc.getName() + "\", name: \"" + fields[numPrimFields + i].getName() + "\", type: \"" + fields[numPrimFields + i].getType() + "\")");
                                        }

                                        try {
                                        		//递归调用了writeObject0
                                                this.writeObject0(objVals[i], fields[numPrimFields + i].isUnshared());
                                        } finally {
                                                if (extendedDebugInfo) {
                                                        this.debugInfoStack.pop();
                                                }

                                        }
                                }
                        }

                }
        }

六、writeExternalData

        private void writeExternalData(Externalizable obj) throws IOException {
                PutFieldImpl oldPut = this.curPut;
                this.curPut = null;
                if (extendedDebugInfo) {
                        this.debugInfoStack.push("writeExternal data");
                }

                SerialCallbackContext oldContext = this.curContext;

                try {
                        this.curContext = null;
                        if (this.protocol == 1) {
                        		//执行序列化对象的writeExternal
                                obj.writeExternal(this);
                        } else {
                                this.bout.setBlockDataMode(true);
                                obj.writeExternal(this);
                                this.bout.setBlockDataMode(false);
                                this.bout.writeByte(120);
                        }
                } finally {
                        this.curContext = oldContext;
                        if (extendedDebugInfo) {
                                this.debugInfoStack.pop();
                        }

                }

                this.curPut = oldPut;
        }
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值