java readobject_关于Java中使用Serializable中readObject和readObject调用的问题

我们都知道,序列化不会自动保存static和transient变量,因此我们若要保存它们,则需要通过writeObject()和readObject()去手动读写。

(01) 通过writeObject()方法,写入要保存的变量。writeObject的原始定义是在ObjectOutputStream.java中,我们按照如下示例覆盖即可:

private void writeObject(ObjectOutputStream out) throws IOException{

out.defaultWriteObject();// 使定制的writeObject()方法可以利用自动序列化中内置的逻辑。

out.writeInt(ival); // 若要保存“int类型的值”,则使用writeInt()

out.writeObject(obj); // 若要保存“Object对象”,则使用writeObject()

}

(02) 通过readObject()方法,读取之前保存的变量。readObject的原始定义是在ObjectInputStream.java中,我们按照如下示例覆盖即可:

private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException{

in.defaultReadObject(); // 使定制的readObject()方法可以利用自动序列化中内置的逻辑。

int ival = in.readInt(); // 若要读取“int类型的值”,则使用readInt()

Object obj = in.readObject(); // 若要读取“Object对象”,则使用readObject()

}

但是你会很惊奇尽管它们被外部类调用但事实上这是两个private的方法。并且它们既不存在于java.lang.Object,也没有在Serializable中声明。那么ObjectOutputStream如何使用它们的呢?

作为程序员我们有一个终极大杀器,就是看源码?

以ObjectInputStream 为例:

首先,会调用readObject(),通过Object obj = readObject0(false);调用readObject0;里面有这一句return checkResolve(readOrdinaryObject(unshared));调用

readOrdinaryObject方法 在readOrdinaryObject会调用readSerialData(obj, desc);然后readSerialData会调用slotDesc.invokeReadObject(obj, this);这里调用ObjectStreamClass的invokeReadObject(Object obj, ObjectInputStream in)

里面 readObjectMethod.invoke(obj, new Object[]{ in });这显然是一个通过发射进行的方法调用,那么readObjectMethod是什么方法?别急继续往下看,到ObjectStreamClass(final Class> cl)

发现里面有这一句readObjectMethod = getPrivateMethod(cl, "readObject",new Class>[] { ObjectInputStream.class },Void.TYPE),getPrivateMethod方法如下:

/**

* Returns non-static private method with given signature defined by given

* class, or null if none found. Access checks are disabled on the

* returned method (if any).

*/

private static Method getPrivateMethod(Class> cl, String name,

Class>[] argTypes,

Class> returnType)

{

try {

Method meth = cl.getDeclaredMethod(name, argTypes);

meth.setAccessible(true);

int mods = meth.getModifiers();

return ((meth.getReturnType() == returnType) &&

((mods & Modifier.STATIC) == 0) &&

((mods & Modifier.PRIVATE) != 0)) ? meth : null;

} catch (NoSuchMethodException ex) {

return null;

}

}

这下总算搞明白了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值