On this page:
Basic Java Mapping for Classes
A Slice class is mapped to a Java class with the same name. The generated class contains a public field for each Slice data member (just as for structures and exceptions). Consider the following class definition:
The Slice compiler generates the following code for this definition:
There are a several things to note about the generated code:
- The generated class
com.zeroc.Ice.Value. This means that all classes implicitly inherit from
Value, which is the ultimate ancestor of all classes.
- The generated class contains a public field for each Slice data member.
- The generated class has a constructor that takes one argument for each field, as well as a default constructor.
There is quite a bit to discuss here, so we will look at each item in turn.
Ice::Value in Java
Classes implicitly inherit from a common base class,
Value, which is mapped to
Value is a very simple base class with just a few methods:
Value methods behave as follows:
The Ice run time invokes this method prior to marshaling the value's state, providing the opportunity for a subclass to validate its declared data members.
The Ice run time invokes this method after unmarshaling a value's state. A subclass typically overrides this method when it needs to perform additional initialization using the values of its declared data members.
cloneThis method returns a shallow member-wise copy of the value.
This method returns the actual run-time type ID for a class instance. If you call
ice_idthrough a reference to a base instance, the returned type id is the actual (possibly more derived) type ID of the instance.
This functions returns the
SlicedDataobject if the value has been sliced during un-marshaling or
Class Data Members in Java
By default, data members of classes are mapped exactly as for structures and exceptions: for each data member in the Slice definition, the generated class contains a corresponding public field. A JavaBean-style API is used for optional data members, and you can customize the mapping to force required members to use this same API.
If you wish to restrict access to a field you can modify its visibility using the
protected metadata directive. The presence of this directive causes the Slice compiler to generate the field with protected visibility. As a result, the field can be accessed only by the class itself or by one of its subclasses. For example, the
TimeOfDay class shown below has the
protected metadata directive applied to each of its data members:
The Slice compiler produces the following generated code for this definition:
For a class in which all of the data members are protected, the metadata directive can be applied to the class itself rather than to each member individually. For example, we can rewrite the
TimeOfDay class as follows:
You can optionally customize the mapping for data members to use getters and setters instead.
Class Constructors in Java
Classes have a default constructor that initializes fields as follows:
|Data Member Type||Default Value|
|First enumerator in enumeration|
The constructor won't explicitly initialize a field if the default Java behavior for that type produces the desired results.
If you wish to ensure that fields of primitive and enumerated types are initialized to specific values, you can declare default values in your Slice definition. The default constructor initializes each of these fields to its declared value instead.
The generated class also contains a second constructor that accepts one argument for each field of the class. This allows you to create and initialize a class in a single statement, for example:
For derived classes, the constructor requires an argument for every member of the class, including inherited members. For example, consider the the definition from Class Inheritance once more:
The constructors for the generated classes are as follows:
If you want to instantiate and initialize a
DateTime instance, you must either use the default constructor or provide values for all the fields of the instance, including fields of any base classes.
Value Factories in Java
Value factories allow you to create classes derived from the Java classes generated by the Slice compiler, and tell the Ice run time to create instances of these classes when unmarshaling. For example, with the following simple interface:
The default behavior of the Ice run time will create and return an instance of the generated
If you wish, you can create your own custom derived class, and tell Ice to create and return these instances instead. For example:
You then create and register a value factory for your custom class with your Ice communicator:
Class Operations in Java
Operations on classes are deprecated as of Ice 3.7. Skip this section unless you need to communicate with old applications that rely on this feature.
Operations in classes are not mapped at all into the corresponding Java class. The generated Java class is the same whether the Slice class has operations or not.
For a class that defines or inherits operations, the Slice-to-Java compiler generates instead a separate
_<class-name>Disp class that can be used to implement an Ice object with these operations. Let's change our example to add a class operation:
The Slice compiler generates the following code:
Disp class is the skeleton class for this Slice class. Skeleton classes are described in the Server-Side Java Mapping for Interfaces.