Java如何反序列化Class对象,同时保留它们与当前加载的Class对象的身份?

gvl*_*sov 7 java serialization classloader

如果我序列化一个Class对象(例如HashMap.class),然后在另一个JVM实例中反序列化它,那么反序列化的类与当前加载的类相同:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;

final class DeserializationTest {

    static String path = "/home/suseika/test.ser";
    static Class<HashMap> cls = HashMap.class;

    public static void main(String[] args) throws Exception {
        if (args[0].equals("serialize")) {
            serialize();
        } else if (args[0].equals("deserialize")) {
            final Object deserialized = deserialize();

            // The important line, prints "true"
            System.out.println(deserialized == cls); 
        }
    }

    static Object deserialize() throws Exception {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(path));
        return in.readObject();
    }

    static void serialize() throws Exception {
        FileOutputStream fileOut = new FileOutputStream(path);
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        out.writeObject(cls);
        out.close();
        fileOut.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Java如何能够反序列化对象,以便保留身份?Class似乎没有实现writeObject()/ readObject()/ readResolve().

加载特定的类/使用特定的类加载器/使用特定的JVM设置/在序列化期间做某事可以打破这种行为吗?是否存在加载Class与反序列化的加载不一样的情况?换句话说,我可以在我的应用程序中依赖此行为来序列化和反序列化Class对象吗?

ide*_*all 2

在这种情况下,Java 如何反序列化对象以保留身份?

这是因为类实例由类加载器缓存。

Java 是否保证 Object.getClass() == Object.getClass()?

可以通过加载特定类/使用特定类加载器/使用特定 JVM 设置/在序列化期间执行某些操作来打破此行为吗?

对于不以此开头的包中的类的序列化实例,java.*可以使用不同的类加载器来破坏(此处的ObjectInputStream示例 )。

对于java.*像您的情况(java.lang.Class)这样的类,只有 Bootstrap 类加载器可以加载它们,并且考虑到每个类加载器的类定义都是唯一的(由JVM 规范保证)

换句话说,我可以依靠应用程序中的这种行为来序列化和反序列化 Class 对象吗

是的