Serialization: Understand 'readsolve'

Source: Internet
Author: User
Tags object serialization
What are the writereplace () and readresolve () Methods used?

These methods are used to allow an object to provide an alternative representation for itself withinObjectstream. Consider for instance the common means of implementing an enumerated type:

public class Gender implements Serializable {  public final static Gender MALE   = new Gender("Male");  public final static Gender FEMALE = new Gender("Female");  private String name;  private Gender(String name) {    this.name = name;  }}
This works fine within one JVM; There will be at most two GenderObjects Created, no matter how often you use Gender. MaleAnd Gender. FemaleIn your code. However, consider what happens when an instance of this class is serialized into SS JVMs. ObjectinputstreamWill create a new instance GenderThat has the same value as the original Instance. So, if you have your thousands objects that have been de-serialized via RMI you might end up with your thousands of extra instances Gender. Writereplace ()And Readresolve ()Methods are the hook to solve this problem.

 

One way of eliminating the extra instances and some of the unnecessary heap allocation wocould be to do something like this:

public class Gender implements Serializable {  public final static Gender MALE   = new Gender("Male");  public final static Gender FEMALE = new Gender("Female");  private String name;  private Gender(String name) {    this.name = name;  }  Object writeReplace() throws ObjectStreamException {    if (this.equals(MALE)) {      return SerializedForm.MALE_FORM;    } else {      return SerializedForm.FEMALE_FORM;    }  }  private static class SerializedForm implements Serializable {    final static SerializedForm MALE_FORM   = new SerializedForm(0);    final static SerializedForm FEMALE_FORM = new SerializedForm(1);    private int value;    SerializedForm(int value) {      this.value = value;    }    Object readResolve() throws ObjectStreamException {      if (value == MALE_FORM.value) {        return Gender.MALE;      } else {        return Gender.FEMALE;      }    }  }}
This also guarantees that in all cases where Genderinstance. Equals (male)Is true, Genderinstance = gender. MaleIs also true.

Serialization is a handy and powerful aspect of Java. being able to persist objects onto disk and read them later is one of the most under-used features of Java I think. in the base cases, serialization can 'just work '. however, as more complicated object formats and design patterns are adopted, the likelihood that 'transparent' Object serialization will 'just work' becomes less and less likely. one case where serialization needs a little help is when dealing with a controlled set of instances-such as singletons and enumerations.

Whenever a singleton is serializable, it's important to ensure that the singleton instance is used. This is done throughreadResolve Method. For instance, a singleton may look like this:

 

public final class MySingleton { private MySingleton() { } private static final MySingleton INSTANCE = new MySingleton(); public static MySingleton getInstance() { return INSTANCE; }}

 

In the above example, there is only one way to get an instanceMySingleton -That is to usegetInstance() Method. Unfortunately, this code becomes 'broken' simply by adding one interface implementation:

 

public final class MySingleton implements Serializable {//...

 

Now through the serializable tools, someone can write a singleton instance to disk, and then read it back up, using tively getting a new instance. even though the constructor is private, the serializable tools have special access to create instances of a class regardless. serialization has a special hook it uses-a private method on the class being instantiated calledreadResolve() -Which is meant to supply a 'hook 'for a class developer to ensure that they have a say in what object is returned by serialization. Oddly enough,readResolve() Is not static, but is instead invoked on the new instance just created by the serialization. We'll get into that in a minute-for now, here is how ourreadResolve() Method works with our singleton:

 

public final class MySingleton { private MySingleton() { } private static final MySingleton INSTANCE = new MySingleton(); public static MySingleton getInstance() { return INSTANCE; } private Object readResolve() throws ObjectStreamException {  // instead of the object we‘re on,   // return the class variable INSTANCE  return INSTANCE;  }}

 

So far so good. things get a little complicated when dealing with more than one instance however. to explain this, I'll show this using a type-safe enumeration. keep in mind that Java 5senum Type automatically handles thisreadResolve Case for you. Here is a nice little enumeration:

 

public final class Sides { private int value; private Sides(int newVal) { value = newVal; } private static final int LEFT_VALUE = 1; private static final int RIGHT_VALUE = 2; private static final int TOP_VALUE = 3; private static final int BOTTOM_VALUE = 4;  public static final LEFT = new Sides(LEFT_VALUE); public static final RIGHT = new Sides(RIGHT_VALUE); public static final TOP = new Sides(TOP_VALUE); public static final BOTTOM = new Sides(BOTTOM_VALUE); }

 

Now, implementing serialization, the key to determining which instance to return is in inspecting what value is set on the object itself:

 

public final class Sides implements Serializable { private int value; private Sides(int newVal) { value = newVal; } private static final int LEFT_VALUE = 1; private static final int RIGHT_VALUE = 2; private static final int TOP_VALUE = 3; private static final int BOTTOM_VALUE = 4;  public static final LEFT = new Sides(LEFT_VALUE); public static final RIGHT = new Sides(RIGHT_VALUE); public static final TOP = new Sides(TOP_VALUE); public static final BOTTOM = new Sides(BOTTOM_VALUE);  private Object readResolve() throws ObjectStreamException {  // Switch on this instance‘s value to figure out which class variable  // this is meant to match  switch(value) {   case LEFT_VALUE: return LEFT;   case RIGHT_VALUE: return RIGHT;   case TOP_VALUE: return TOP;   case BOTTOM_VALUE: return BOTTOM;    }  return null; }}

Serialization: Understand 'readsolve'

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.