在Java中实现对象反序列化非常简单,实现java.io.Serializable(内部序列化)java.io.Externalizable(外部序列化)接口即可被序列化,其中java.io.Externalizable接口只是实现了java.io.Serializable接口。

    反序列化类对象时有如下限制:

    1. 被反序列化的类必须存在。
    2. serialVersionUID值必须一致。

    除此之外,反序列化类对象是不会调用该类构造方法的,因为在反序列化创建类实例时使用了sun.reflect.ReflectionFactory.newConstructorForSerialization创建了一个反序列化专用的Constructor(反射构造方法对象),使用这个特殊的Constructor可以绕过构造方法创建类实例(前面章节讲sun.misc.Unsafe 的时候我们提到了使用allocateInstance方法也可以实现绕过构造方法创建类实例)。

    使用反序列化方式创建类实例代码片段:

    1. package com.anbai.sec.serializes;
    2. import sun.reflect.ReflectionFactory;
    3. import java.lang.reflect.Constructor;
    4. /**
    5. * 使用反序列化方式在不调用类构造方法的情况下创建类实例
    6. * Creator: yz
    7. * Date: 2019/12/20
    8. */
    9. public class ReflectionFactoryTest {
    10. public static void main(String[] args) {
    11. try {
    12. // 获取sun.reflect.ReflectionFactory对象
    13. ReflectionFactory factory = ReflectionFactory.getReflectionFactory();
    14. // 使用反序列化方式获取DeserializationTest类的构造方法
    15. Constructor constructor = factory.newConstructorForSerialization(
    16. DeserializationTest.class, Object.class.getConstructor()
    17. );
    18. // 实例化DeserializationTest对象
    19. System.out.println(constructor.newInstance());
    20. } catch (Exception e) {
    21. e.printStackTrace();
    22. }
    23. }
    24. }

    程序运行结果:

    1. com.anbai.sec.serializes.DeserializationTest@2b650cea

    具体细节可参考 不用构造方法也能创建对象