标签:启用 无法 check cto nali 方法注释 pack int 子类
对象要想序列化,需要类实现接口 Serializable与Externalizable其中之一
Externalizable接口继承自Serializable,但是增加了两个方法即writeExternal方法和readExternal方法
在writeExternal方法中,自定定制哪些属性要序列化,顺序是什么样。
在readExternal方法中,自定定制哪些属性要反序列化,顺序和writeExternal的方法中一致。
查找ObjectStreamClass源码 找到一个方法
private static Constructor<?> getSerializableConstructor(Class<?> cl) { Class<?> initCl = cl; while (Serializable.class.isAssignableFrom(initCl)) { if ((initCl = initCl.getSuperclass()) == null) { return null; } } try { Constructor<?> cons = initCl.getDeclaredConstructor((Class<?>[]) null); int mods = cons.getModifiers(); if ((mods & Modifier.PRIVATE) != 0 || ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && !packageEquals(cl, initCl))) { return null; } cons = reflFactory.newConstructorForSerialization(cl, cons); cons.setAccessible(true); return cons; } catch (NoSuchMethodException ex) { return null; } }
方法注释为:
Returns subclass-accessible no-arg constructor of first non-serializable superclass, or null if none found. Access checks are disabled on the returned constructor (if any)。
即:该方法会返回Serializable接口实现类往上一直寻找到第一个没有实现该接口父类的空参构造方法,若第一个没有实现该接口的父类没有空参构造方法,则会抛出java.io.InvalidClassException: IO.goods; no valid constructor异常,如果该实现类有无空参构造都可以,但是第一个没有实现该接口的父类必须有
同样的,查找ObjectStreamClass源码发现,
private static Constructor<?> getExternalizableConstructor(Class<?> cl) { try { Constructor<?> cons = cl.getDeclaredConstructor((Class<?>[]) null); cons.setAccessible(true); return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ? cons : null; } catch (NoSuchMethodException ex) { return null; } }
该方法注释为:
Returns public no-arg constructor of given class, or null if none found. * Access checks are disabled on the returned constructor (if any), since * the defining class may still be non-public.
即;查找实现类是否有空参构造,如果没有则返回null,
因此Externalizable接口实现类必须有空参构造方法,否则反序列化时会抛出 java.io.InvalidClassException异常。
标签:启用 无法 check cto nali 方法注释 pack int 子类
原文地址:https://www.cnblogs.com/csyxwk/p/13278483.html