Reputation: 20025
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?
Upvotes: 7
Views: 2604
Reputation: 1661
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
Upvotes: 2
Reputation: 310957
How is Java able to deserialize objects in this case so that identity is preserved?
Class
doesn't seem to implementwriteObject()/readObject()/readResolve()
.
It doesn't need to implement readObject()
or writeObject()
to accomplish this, but it could do it by implementing readResolve()
, or by special logic in ObjectInputStream
.
Upvotes: 0