public abstract class Instantiator
extends java.lang.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,
Class.forName(java.lang.String)DataSerializable.fromData(java.io.DataInput) is invoked on the
newly-created objectDataSerializable 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();
}
}
Instantiators 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.
register(Instantiator),
newInstance()| Constructor and Description |
|---|
Instantiator(java.lang.Class<? extends DataSerializable> c,
int classId)
Creates a new
Instantiator that instantiates a given
class. |
| Modifier and Type | Method and Description |
|---|---|
java.lang.Object |
getContext()
Returns the context of this
Instantiator. |
java.lang.Object |
getEventId()
Returns the unique
eventId of this
Instantiator. |
int |
getId()
Returns the unique
id of this
Instantiator. |
java.lang.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(java.lang.Object context)
sets the context of this
Instantiator. |
void |
setEventId(java.lang.Object eventId)
sets the unique
eventId of this
Instantiator. |
public Instantiator(java.lang.Class<? extends DataSerializable> c, int classId)
Instantiator that instantiates a given
class.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.java.lang.IllegalArgumentException - If c does not implement
DataSerializable, classId is
less than or equal to zero.java.lang.NullPointerException - If c is nullpublic static void register(Instantiator instantiator)
DataSerializable class with the data
serialization framework. This method is usually invoked from the
static initializer of a class that implements
DataSerializable.instantiator - An Instantiator whose newInstance()
method is invoked when an object is data deserialized.java.lang.IllegalStateException - If class c is
already registered with a different class id, or another
class has already been registered with id
classIdjava.lang.NullPointerException - If instantiator is null.public static void register(Instantiator instantiator, boolean distribute)
register(Instantiator) insteadDataSerializable class with the data
serialization framework. This method is usually invoked from the
static initializer of a class that implements
DataSerializable.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.java.lang.IllegalArgumentException - If class c is
already registered with a different class id, or another
class has already been registered with id
classIdjava.lang.NullPointerException - If instantiator is null.public abstract DataSerializable newInstance()
DataSerializable
class whose state will be filled in by invoking its fromData method.public final java.lang.Class<? extends DataSerializable> getInstantiatedClass()
DataSerializable class that is
instantiated by this Instantiator.public final int getId()
id of this
Instantiator.public final void setEventId(java.lang.Object eventId)
eventId of this
Instantiator. For internal use only.public final java.lang.Object getEventId()
eventId of this
Instantiator. For internal use only.public final void setContext(java.lang.Object context)
Instantiator. For internal use only.public final java.lang.Object getContext()
Instantiator. For internal use only.