A serializable class is defined as
public class Elvis implements Serializable {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { }
private String[] favoriteSongs ={ "Hound Dog", "Heartbreak Hotel" };
public void printFavorites() {
System.out.println(Arrays.toString(favoriteSongs));
}
private Object readResolve() {
return INSTANCE;
}
}
A stealer class is defined as
public class ElvisStealer implements Serializable {
static Elvis impersonator;
private Elvis payload;
private Object readResolve() {
// Save a reference to the "unresolved" Elvis instance
impersonator = payload;
// Return object of correct type for favoriteSongs field
return new String[] { "A Fool Such as I" };
}
private static final long serialVersionUID =0;
}
Finally, here is the program.
public class ElvisImpersonator {
// Byte stream couldn't have come from a real Elvis instance!
private static final byte[] serializedForm = {
(byte)0xac, (byte)0xed, 0x00, 0x05, 0x73, 0x72, 0x00, 0x05,
0x45, 0x6c, 0x76, 0x69, 0x73, (byte)0x84, (byte)0xe6,
(byte)0x93, 0x33, (byte)0xc3, (byte)0xf4, (byte)0x8b,
0x32, 0x02, 0x00, 0x01, 0x4c, 0x00, 0x0d, 0x66, 0x61, 0x76,
0x6f, 0x72, 0x69, 0x74, 0x65, 0x53, 0x6f, 0x6e, 0x67, 0x73,
0x74, 0x00, 0x12, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
0x3b, 0x78, 0x70, 0x73, 0x72, 0x00, 0x0c, 0x45, 0x6c, 0x76,
0x69, 0x73, 0x53, 0x74, 0x65, 0x61, 0x6c, 0x65, 0x72, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
0x4c, 0x00, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x74, 0x00, 0x07, 0x4c, 0x45, 0x6c, 0x76, 0x69, 0x73, 0x3b,
0x78, 0x70, 0x71, 0x00, 0x7e, 0x00, 0x02
};
public static void main(String[] args) {
// Initializes ElvisStealer.impersonator and returns
// the real Elvis (which is Elvis.INSTANCE)
Elvis elvis = (Elvis) deserialize(serializedForm);
Elvis impersonator = ElvisStealer.impersonator;
elvis.printFavorites();
impersonator.printFavorites();
}
}
Here is the output of the program.
[Hound Dog, Heartbreak Hotel]
[A Fool Such as I]
Here is the structralized serialized form.

While I read this part,
- I don't know why the return of the method readResolve() of ElvisStealer can change the favoriteSongs field of impersonator?
- Why 0x71, 0x00, 0x7e, 0x00, 0x02 is the reference of Elvis?
- Why 0x71, 0x00, 0x7e, 0x00, 0x02 will be assigned to field payload of ElvisStealer?
I think it helps if you understand how Java Serialization works.
Basically, if an object is serialized the stored data is:
For objects that have been written previously the serialization stores a code value that means "use that previous instance" (in Java Serialization terms: a back reference).
If the object is read back, the process is:
readResolve()method exists call that method and use the result of that method as resultWith the payload from
serializedFormthe complete process is:ElvisElvisinstancefavoriteSongs:ElvisStealerElvisStealerinstancepayloadElvisinstance created in step 20x71 0x00 0x7e 0x00 0x02at the end of the serialized datareadResolve()method ofElvisStealerwhich saves thepayloadintoElvisStealer.impersonatorand then returnsnew String[] { "A Fool Such as I" }new String[] { "A Fool Such as I" }is stored asfavoriteSongsof theElvisinstance created in step 2readResolve()method ofElviswhich returnsElvis.INSTANCEas resultElvis.INSTANCEis the final result of thedeserialize()call.Why is this
0x71 0x00 0x7e 0x00 0x02the reference to theElvisinstance created in step 2?The breakdown of
0x71 0x00 0x7e 0x00 0x02is:0x71:TC_REFERENCE0x00 0x7e 0x00 0x02: the value 0x7e0002 which isbaseWireHandle+ 2The java serialization mechanism stores "interesting entries" in the data stream into a
HandleTable handlesso that later on - if the same "interesting entry" appears again - it can store just a short back reference to that "interesting entry" instead of writing the whole thing again.In your example the "interesting entries" are:
Elvisclass (class name, serialVersionUID, flags, information about the fields)Ljava/lang/Object;- the binary name of the classjava.lang.Objectwhich is the class type of thefavoriteSongsfield in the serialized dataElvisinstanceElvisStealerclassLElvis;- the binary name of the classElviswhich is the class type of thepayloadfield in the serialized dataElvisStealerinstanceThis table is not predefined somewhere in the serialized data - it is reconstructed during the deserialization process.
There is no simple rule "the first object is always the number 2" - that very much depends on how many serializable super classes that class of that first object has and how many fields the class and its serializable super classes have.