How does Java deserialize class objects while maintaining their identity for loadable class objects?

If I serialize a Class object (for example, HashMap.class ) and then deserialize it in another JVM instance, 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 can Java deserialize objects in this case to maintain identity? Class does not seem to implement writeObject() / readObject() / readResolve() .

Can this behavior be violated when loading a certain class / using a specific class loader / using a specific JVM installation / do something during serialization? Are there cases where a loaded Class will not be the same as a deserialized one? In other words, can I rely on this behavior in my application to serialize and deserialize Class objects?

+6
source share
2 answers

How can Java deserialize objects in this case to maintain identity?

This is because instance instances are cached by the class loader.

Does Java guarantee that Object.getClass () == Object.getClass ()?

Can this behavior be violated when loading a certain class / using a specific class loader / using a specific JVM installation / do something during serialization?

For serialized class instances from packages that do not start with java.* , This can be broken using different class loaders in ObjectInputStream (example here ).

For classes in java.* Similar to your case ( java.lang.Class ), the loader can only load the Bootstrap class loader, and given that the class definition is unique to each class loader (guaranteed JVM Specification )

In other words, can I rely on this behavior in my application to serialize and deserialize class objects

Yes

+2
source

How can Java deserialize objects in this case to maintain identity? Class does not seem to implement writeObject()/readObject()/readResolve() .

To accomplish this, you do not need to implement readObject() or writeObject() , but you can do this by implementing readResolve() or special logic in ObjectInputStream .

0
source

All Articles