If I serialize a Class
object (for example, HashMap.class
), and then deserialize it in another instance of JVM, it turns out that the deserialized class is identical to the one currently loaded:
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();
}
}
How is Java able to deserialize objects in this case so that identity is preserved? Class
doesn't seem to implement writeObject()
/readObject()
/readResolve()
.
Can this behavior be broken with loading a particular class/using a particular classloader/using a particular JVM setup/doing something during serialization? Are there instances where the loaded Class
would not be the same as the deserialized one? In other words, can I rely on this behavior in my application to serialize and deserialize Class
objects?
How is Java able to deserialize objects in this case so that identity is preserved?
This is because class instances are cached by the classloader.
Does Java guarantee that Object.getClass() == Object.getClass()?
Can this behavior be broken with loading a particular class/using a particular classloader/using a particular JVM setup/doing something during serialization?
For serialized instances of classes from packages not starting with java.*
this can be broken using different classloaders in ObjectInputStream
(an example here).
For classes in java.*
like your case (java.lang.Class
), only the Bootstrap class loader can load them, and given that class definition is unique per class loader (guaranteed by the JVM spec)
In other words, can I rely on this behavior in my application to serialize and deserialize Class objects
Yes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With