Table 6.1 summarizes the types found in Java. Only primitive data and reference values can be stored in variables . Only class and array types can be instantiated to create objects. Table 6.1. Types and Values
Arrays are objects in Java. Array types ( boolean[] , Object[] , StackImpl[] ) implicitly augment the inheritance hierarchy. The inheritance hierarchy depicted in Figure 6.3 can be augmented by the corresponding array types. The resulting type hierarchy is shown in Figure 6.4. An array type is shown as a "class" with the [] notation appended to the name of the element type. The class SafeStackImpl is a subclass of the class StackImpl . The corresponding array types, SafeStackImpl[] and StackImpl[] , are shown as subtype and supertype , respectively, in the type hierarchy. Figure 6.4 also shows array types corresponding to some of the primitive data types. Figure 6.4. Reference Type Hierarchy
From the type hierarchy in Figure 6.4, we can summarize the following:
We can create an array of an interface type, but we cannot instantiate an interface (as is the case with abstract classes). In the declaration statement below, the reference iSafeStackArray has type ISafeStack[] , (i.e., array of interface type ISafeStack ). The array creation expression creates an array whose element type is ISafeStack . The array object can accommodate five references of type ISafeStack . The following statement does not initialize these references to denote any objects: ISafeStack[] iSafeStackArray = new ISafeStack[5]; An array reference exhibits polymorphic behavior like any other reference, subject to its location in the type hierarchy (see Section 6.7, p. 272). However, a runtime check can be necessary when objects are inserted in an array, as the following example illustrates. The following assignment is valid, as a supertype reference ( StackImpl[] ) can denote objects of its subtype ( SafeStackImpl[] ): StackImpl[] stackImplArray = new SafeStackImpl[2]; // (1) Since StackImpl is a supertype of SafeStackImpl , the following assignment is also valid: stackImplArray[0] = new SafeStackImpl(10); // (2) The assignment at (2) inserts a SafeStackImpl object in the SafeStackImpl[] object (i.e., array of SafeStackImpl ) created at (1). Since the type of stackImplArray[i] , ( i < 2 ), is StackImpl , it should be possible to do the following assignment as well: stackImplArray[1] = new StackImpl(20); // (3) ArrayStoreException At compile time there are no problems, as the compiler cannot deduce that the array variable stackImplArray will actually denote an SafeStackImpl[] object at runtime. However, the assignment at (3) causes an ArrayStoreException to be thrown at runtime, as a SafeStackImpl[] object cannot possibly contain objects of type StackImpl . |