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,
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(); } }
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.
register(Instantiator)
,
newInstance()
Constructor and Description |
---|
Instantiator(Class<? extends DataSerializable> c,
int classId)
Creates a new
Instantiator that instantiates a given class. |
Modifier and Type | Method and 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 . |
public Instantiator(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.IllegalArgumentException
- If c
does not implement DataSerializable
,
classId
is less than or equal to zero.NullPointerException
- If c
is null
public 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.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
.@Deprecated 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.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
.public abstract DataSerializable newInstance()
DataSerializable
class whose state will be filled
in by invoking its fromData
method.DataSerializable
classDataSerializer.readObject(java.io.DataInput)
public Class<? extends DataSerializable> getInstantiatedClass()
DataSerializable
class that is instantiated by this Instantiator
.DataSerializable
class that is instantiated by this Instantiator
public int getId()
id
of this Instantiator
.id
of this Instantiator
public void setEventId(Object eventId)
eventId
of this Instantiator
. For internal use only.eventId
- the unique eventId
of this Instantiator
public Object getEventId()
eventId
of this Instantiator
. For internal use only.eventId
of this Instantiator
public void setContext(Object context)
Instantiator
. For internal use only.context
- the context of this Instantiator
public Object getContext()
Instantiator
. For internal use only.Instantiator