Instantiator (Apache Geode 2.0.2)
Description: declaration: package: org.apache.geode, class: Instantiator

Package org.apache.geode

# Class Instantiator

java.lang.Object
org.apache.geode.Instantiator

Direct Known Subclasses:
  `CanonicalInstantiator`

public abstract class Instantiator extends Object
`Instantiator` allows classes that implement `DataSerializable` to be registered with the data serialization framework. Knowledge of `DataSerializable` classes allows the framework to optimize how instances of those classes are data serialized.

Ordinarily, when a `DataSerializable` object is written using `DataSerializer.writeObject(Object, java.io.DataOutput)`, a special marker class id is written to the stream followed by the class name of the `DataSerializable` object. After the marker class id is read by `DataSerializer.readObject(java.io.DataInput)` it performs the following operations,

1. The class name is read
2. The class is loaded using `Class.forName(java.lang.String)`
3. An instance of the class is created using reflection
4. `DataSerializable.fromData(java.io.DataInput)` is invoked on the newly-created object

However, if a `DataSerializable` class is registered with the data serialization framework and assigned a unique class id, an important optimization can be performed that avoid the expense of using reflection to instantiate the `DataSerializable` class. When the object is written using `DataSerializer.writeObject(Object, java.io.DataOutput)`, the object's registered class id is written to the stream. Consequently, when the data is read from the stream, the `newInstance()` method of the appropriate `Instantiator` instance is invoked to create an "empty" instance of the `DataSerializable` instead of using reflection to create the new instance.

Commonly, a `DataSerializable` class will register itself with the `Instantiator` in a static initializer as shown in the below example code.

    public class User implements DataSerializable {
      private String name;
      private int userId;

      static {
        Instantiator.register(new Instantiator(User.class, 45) {
            public DataSerializable newInstance() {
              return new User();
            }
          });
      }

      public User(String name, int userId) {
        this.name = name;
        this.userId = userId;
      }

      /**
     Creates an "empty" User whose contents are filled in by
     invoking its toData() method
    /
      private User() {

      }

      public void toData(DataOutput out) throws IOException {
        out.writeUTF(this.name);
        out.writeInt(this.userId);
      }

      public void fromData(DataInput in)
        throws IOException, ClassNotFoundException {
        this.name = in.readUTF();
        this.userId = in.readInt();
      }
    }

`Instantiator`s may be distributed to other members of the distributed system when they are registered. Consider the following scenario in which VM1 and VM2 are members of the same distributed system. Both VMs define the sameRegion and VM2's region replicates the contents of VM1's using replication. VM1 puts an instance of the above `User` class into the region. The act of instantiating `User` will load the `User` class and invoke its static initializer, thus registering the `Instantiator` with the data serialization framework. Because the region is a replicate, the `User` will be data serialized and sent to VM2. However, when VM2 attempts to data deserialize the `User`, its `Instantiator` will not necessarily be registered because `User`'s static initializer may not have been invoked yet. As a result, an exception would be logged while deserializing the `User` and the replicate would not appear to have the new value. So, in order to ensure that the `Instantiator` is registered in VM2, the data serialization framework distributes a message to each member when an `Instantiator` is registered.

Note that the framework does not require that an `Instantiator` be `Serializable`, but it does require that it provide a two-argument constructor.

Since:
  GemFire 3.5
See Also:
  - `register(Instantiator)`
  - `newInstance()`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `Instantiator(Class<? extends DataSerializable> c, int classId)`
  Creates a new `Instantiator` that instantiates a given class.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `Object`
  `getContext()`
  Returns the context of this `Instantiator`.
  `Object`
  `getEventId()`
  Returns the unique `eventId` of this `Instantiator`.
  `int`
  `getId()`
  Returns the unique `id` of this `Instantiator`.
  `Class<? extends DataSerializable>`
  `getInstantiatedClass()`
  Returns the `DataSerializable` class that is instantiated by this `Instantiator`.
  `abstract DataSerializable`
  `newInstance()`
  Creates a new "empty" instance of a `DataSerializable` class whose state will be filled in by invoking its `fromData` method.
  `static void`
  `register(Instantiator instantiator)`
  Registers a `DataSerializable` class with the data serialization framework.
  `static void`
  `register(Instantiator instantiator, boolean distribute)`
  Deprecated.
  as of 9.0 use `register(Instantiator)` instead
  `void`
  `setContext(Object context)`
  sets the context of this `Instantiator`.
  `void`
  `setEventId(Object eventId)`
  sets the unique `eventId` of this `Instantiator`.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### Instantiator

    public Instantiator(Class<? extends DataSerializable> c, int classId)
    Creates a new `Instantiator` that instantiates a given class.
    Parameters:
      `c` - The `DataSerializable` class to register. This class must have a static initializer that registers this `Instantiator`.
      `classId` - A unique id for class `c`. The `classId` must not be zero. This has been an `int` since dsPhase1.
    Throws:
      `IllegalArgumentException` - If `c` does not implement `DataSerializable`, `classId` is less than or equal to zero.
      `NullPointerException` - If `c` is `null`

- ## Method Details

  - ### register

    public static void register(Instantiator instantiator)
    Registers a `DataSerializable` class with the data serialization framework. This method is usually invoked from the static initializer of a class that implements `DataSerializable`.
    Parameters:
      `instantiator` - An `Instantiator` whose `newInstance()` method is invoked when an object is data deserialized.
    Throws:
      `IllegalStateException` - If class `c` is already registered with a different class id, or another class has already been registered with id `classId`
      `NullPointerException` - If `instantiator` is `null`.

  - ### register

    @Deprecated public static void register(Instantiator instantiator, boolean distribute)
    Deprecated.
    as of 9.0 use `register(Instantiator)` instead
    Registers a `DataSerializable` class with the data serialization framework. This method is usually invoked from the static initializer of a class that implements `DataSerializable`.
    Parameters:
      `instantiator` - An `Instantiator` whose `newInstance()` method is invoked when an object is data deserialized.
      `distribute` - True if the registered `Instantiator` has to be distributed to other members of the distributed system. Note that if distribute is set to false it may still be distributed in some cases.
    Throws:
      `IllegalArgumentException` - If class `c` is already registered with a different class id, or another class has already been registered with id `classId`
      `NullPointerException` - If `instantiator` is `null`.

  - ### newInstance

    public abstract DataSerializable newInstance()
    Creates a new "empty" instance of a `DataSerializable` class whose state will be filled in by invoking its `fromData` method.
    Returns:
      a new "empty" instance of a `DataSerializable` class
    See Also:
      - `DataSerializer.readObject(java.io.DataInput)`

  - ### getInstantiatedClass

    public Class<? extends DataSerializable> getInstantiatedClass()
    Returns the `DataSerializable` class that is instantiated by this `Instantiator`.
    Returns:
      the `DataSerializable` class that is instantiated by this `Instantiator`

  - ### getId

    public int getId()
    Returns the unique `id` of this `Instantiator`.
    Returns:
      the unique `id` of this `Instantiator`

  - ### setEventId

    public void setEventId(Object eventId)
    sets the unique `eventId` of this `Instantiator`. For internal use only.
    Parameters:
      `eventId` - the unique `eventId` of this `Instantiator`

  - ### getEventId

    public Object getEventId()
    Returns the unique `eventId` of this `Instantiator`. For internal use only.
    Returns:
      the unique `eventId` of this `Instantiator`

  - ### setContext

    public void setContext(Object context)
    sets the context of this `Instantiator`. For internal use only.
    Parameters:
      `context` - the context of this `Instantiator`

  - ### getContext

    public Object getContext()
    Returns the context of this `Instantiator`. For internal use only.
    Returns:
      the context of this `Instantiator`