The final cautionary note relates to one's choice of types for new metadata. Obviously, one can successfully use any subclass of Object, including arrays (e.g. double[], int[], etc.), as long as the metadata ``readers'' and ``writers'' are consistant in the use of the types. However, one should use caution when the value object is of a class type containing internal data that can be updated. Examples of this include java.util.Vector, java.util.BitSet, java.awt.Rectangle, and any Java array. Classes like these contain either public member fields or methods with names like setParamter() that update protected internal data. The reason caution is necessary with these classes is that a client object can obtain a reference to the value (via getMetadatum) and then update its internal data; this will affect not only other objects that already have a reference to the metadatum value, but it will also affect those that obtain a reference via getMetadatum in the future. In a sense, the contents of the Metadata list will have been updated without calling the put method.
Classes like Double and Integer can not be updated and therefore are safe from this effect. The only way a client can update the effective contents of a Metadata list containing only non-updatable objects is via an explicit call of a Metadata method (or method of one of its super- or sub-classes).
The ``horizon'' schema avoids the use updatable class types for metadatum values, with three exceptions: Metadata, Metavector, and Metarunner. The latter two classes are described in the next two sections. The Metadata class knows about these other classes, and can take special precautions to protect this data from updates when necessary. §2.3 describes this capability in more detail. Where the ``horizon'' schema does define metadata to have types that are updateable (like ``defaultSlice'' and ``dataVolume''), Horizon classes will wrap them with the Metarunner object, ObjectCloner (see §2.5 for more details).