Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6176120

RFE: Define annotation to link constructor parameters to getters



    • Type: Enhancement
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 6
    • Fix Version/s: 6
    • Component/s: client-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
    • CPU:
    • OS:


      Currently, when a framework needs to reconstruct an instance of a Java Bean based on any serialized form, it typically does so by requiring that the Bean have a no-arg constructor and a setter for every getter. An object that was serialized by calling all the getters can then be deserialized by calling the constructor and all the setters. This is what XMLDecoder does, unless a class has been explicitly configured with a PersistenceDelegate. Writing a PersistenceDelegate is not trivial, and is specific to the java.beans.Encoder framework. It typically is not useful for serialization to XML schemas a la JAXB, for example. Similarly, we would like to be able to establish a two-way translation between a Java Bean and an instance of javax.management.openmbean.CompositeData in the JMX API.

      Deserialization by calling a no-arg constructor followed by setters is not good because it requires there to be setters. It should be possible for value classes to be immutable, yet deserializable. Immutability has obvious benefits with respect to security and thread-safety.

      A simple improvement would be to define an annotation @PropertyNames that can be attached to a constructor to establish the relationship between the constructor parameters and the class's properties. This is exactly what the constructor
      DefaultPersistenceDelegate(String[] constructorPropertyNames)
      does. Defining the annotation removes the need to code a DefaultPersistenceDelegate explicitly, and it is useful outside the java.beans framework. The definition could be something like this:
      @Documented @Target(CONSTRUCTOR) @Retention(RUNTIME)
      public @interface PropertyNames {
          String[] value();
      This annotation could be applied to all of the classes currently hardwired inside java.beans.MetaData so that the information on how to reconstruct them is generally available rather than being hidden.
      ###@###.### 10/8/04 12:45 GMT

      Example usage:
      public class Rectangle {
          @PropertyNames({"x", "y", "width", "height"})
          public Rectangle(int x, int y, int width, int height) {...}
      It is an error for more than one constructor in a class to have this annotation.
      ###@###.### 10/8/04 13:00 GMT

      In fact it should *not* be an error for more than one constructor to have this annotation. That can easily arise with schema evolution. If the Rectangle example acquires a "color" property then we should still be able to construct an instance of it using a set of properties that were saved from the earlier version that didn't have that property. So we would do something like this:

      public class Rectangle {
          @PropertyNames({"x", "y", "width", "height"})
          public Rectangle(int x, int y, int width, int height) {
              this(x, y, width, height, DEFAULT_COLOR);

          @PropertyNames({"x", "y", "width", "height", "color"})
          public Rectangle(int x, int y, int width, int height, Color color) {...}

      A possible rule (or guideline) could be that if more than one constructor has the annotation, then it must be possible to order the annotated constructors so that the property names for a given constructor are a proper subset of the property names for all later constructors. So each version of a class might add some new properties (like "color" above) and a constructor whose parameters are all the previous properties plus the new ones.

      ###@###.### 2005-04-01 14:53:30 GMT


          Issue Links



              malenkov Sergey Malenkov (Inactive)
              emcmanus Eamonn McManus
              0 Vote for this issue
              2 Start watching this issue