码迷,mamicode.com
首页 > 其他好文 > 详细

序列化,反序列化与空参构造函数

时间:2020-07-10 13:27:06      阅读:67      评论:0      收藏:0      [点我收藏+]

标签:启用   无法   check   cto   nali   方法注释   pack   int   子类   

序列化

对象要想序列化,需要类实现接口 Serializable与Externalizable其中之一

Seializable

  1. 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
  2. 可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。
  3. 如果实现Serializable接口,对象如何序列化,各个属性序列化的顺序是什么,都是默认的,程序员无法指定,也不用关心。
  4. 如果属性前面有static和transient修饰,不参与序列化。

Externalizable

Externalizable接口继承自Serializable,但是增加了两个方法即writeExternal方法和readExternal方法

在writeExternal方法中,自定定制哪些属性要序列化,顺序是什么样。

在readExternal方法中,自定定制哪些属性要反序列化,顺序和writeExternal的方法中一致。

 

先说实现Serializable接口的类对象反序列化时是否需要空参构造。

查找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异常,如果该实现类有无空参构造都可以,但是第一个没有实现该接口的父类必须有

 

实现Externalizable接口的类对象反序列化时是否需要空参构造。

同样的,查找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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!