prev table of contents next

2.2.2 Numeric Types

The schema language features a multi-tiered type hierarchy of built-in numeric datatypes. We'll discuss them briefly in this subsection.

Leaving double and float aside, the root of the tree is given by xsd:decimal. According to the XML Schema definition, this data type represents decimal numbers with an unspecified range of fractional and total digits. There is one Java type providing just that: java.math.BigDecimal. Doing away with fractional digits, we arrive at xsd:integer, which still has an unspecified number of digits; hence java.math.BigInteger must be used. Although both types can be constrained using facets to delimit the number of digits or the value range, the Java code generated by JAXB does not reflect any of this.

Below the integer type, the tree branches off into a hierarchy of non-negative integers, another one for their obscure cousins, the non-positive integers and the traditional line of integer types representing the typical two's complement ranges.

The types long down to byte are normally mapped to Java's eponymous simple types. Exceptions result from the property nillable being set to true for an element or attribute. This adds another value to the set of possible values, i.e., nil, indicating that the element or attribute is simply absent. Java provides null as a convenient value for this abstract nil value - but only for descendants of Object.

The non-negative types comprise xsd:nonNegativeInteger and the unsigned variations of the binary integer types, from xsd:unsignedLong down to xsd:unsignedByte. Since xsd:nonNegativeInteger is defined as a restriction of xsd:integer, it has to be represented by java.math.BigInteger. For xsd:unsignedLong, there is no fitting simple type, and therefore this type maps to java.math.BigInteger, too. With xsd:unsignedInt, xsd:unsignedShort and xsd:unsignedByte, JAXB reverts to simple types, using the smallest type capable of holding all values, e.g., short for xsd:unsignedByte.

The following schema snippet contains a selection of the types discussed so far.

<xsd:complexType name="NumericZooType">
  <xsd:sequence>
    <xsd:element name="decimal"         type="xsd:decimal"/>
    <xsd:element name="integer"         type="xsd:integer"/>
    <xsd:element name="long"            type="xsd:long"/>
    <xsd:element name="int"             type="xsd:int"
                 default="42"/>
    <xsd:element name="short_nil"       type="xsd:short"
                 nillable="true"/>
    <xsd:element name="byte"            type="xsd:byte" 
                 default="13"
                 nillable="true"/>
    <xsd:element name="nonNegative"     type="xsd:nonNegativeInteger"/>
    <xsd:element name="unsignedLong"    type="xsd:unsignedLong"/>
    <xsd:element name="unsignedInt"     type="xsd:unsignedInt"/>
  </xsd:sequence>
</xsd:complexType>
And here is the resulting Java code, simplified for better readability.
public class NumericZooType {

    protected BigDecimal decimal;
    protected BigInteger integer;
    protected long _long;
    protected int _int;
    protected Short shortNil;
    protected Byte _byte;
    protected BigInteger nonNegative;
    protected BigInteger unsignedLong;
    protected long unsignedInt;

    public BigDecimal getDecimal() {
        return decimal;
    }
    public void setDecimal(BigDecimal value) {
        this.decimal = value;
    }

    // All other getters and setters follow the same pattern.
    // ...
}

Well, it's quite a zoo indeed. Although applications dealing with monetary quantities prosper on BigDecimal, schema designers who just want to express a simple integer counter (with a moderate upper limit) are not at all pleased when one of the "Big" types crops up in the generated Java code. So, the question is: can you retain the more convenient simple types while defining suitable value range limits?

The answer is yes, of course, and it's demonstrated in the schema snippet shown below, where a simple type is defined as a restriction of the built-in type xsd:int.

<xsd:simpleType name="CounterType">
  <xsd:restriction base="xsd:int">
    <xsd:minInclusive value="0"/>
  </xsd:restriction>
</xsd:simpleType>

  ...
<xsd:element name="counter" type="CounterType"/>
No separate Java class is generated for CounterType. For some element such as counter, JAXB simply generates the type suitable for the base type of the restriction.
   protected int counter;
   public int getCounter() {
       return counter;
   }
   public void setCounter(int value) {
       this.counter = value;
   }

prev table of contents next