Arrays and the Class Hierarchy

Now we’re going to shift gears a bit and return to the topic of arrays, considering them from the object point of view. At the end of Chapter 4, we mentioned that arrays have a place in the Java class hierarchy, but we didn’t give you any details. Now that we’ve discussed the object-oriented aspects of Java, we can give you the whole story.

Array classes live in a parallel Java class hierarchy under the Object class. If a class is a direct subclass of Object, an array class for that base type also exists as a direct subclass of Object. Arrays of more derived classes are subclasses of the corresponding array classes. For example, consider the following class types:

    class Animal { ... }
    class Bird extends Animal { ... }
    class Penguin extends Bird { ... }

Figure 6-8 illustrates the class hierarchy for arrays of these classes. Arrays of the same dimension are related to one another in the same manner as their base type classes. In our example, Bird is a subclass of Animal, which means that the Bird[] type is a subtype of Animal[]. In the same way a Bird object can be used in place of an Animal object, a Bird[] array can be assigned to a variable of type Animal[]:

    Animal [][] animals;
    Bird [][] birds = new Bird [10][10];
    birds[0][0] = new Bird();

    // make animals and birds reference the same array object
    animals = birds;
    observe( animals[0][0] );               // processes Bird object

Because arrays are part of the class hierarchy, we can use instanceof to check the type of an array:

    if ( birds instanceof Animal[][] )      // true

An array is a type of Object and thus can be assigned to Object type variables:

    Object obj = animals;

Because Java knows the actual type of all objects, you can also cast back if appropriate:

    animals = (Animal [][])something;
Arrays in the Java class hierarchy

Figure 6-8. Arrays in the Java class hierarchy

ArrayStoreException

Because arrays have the property that an array of one type is assignable to an array of its supertype, it is possible to play games with the compiler and try to trick it into storing the wrong kind of object in an array. Java may not be able to check the types of all objects that you place into arrays at compile time. In those cases, it’s possible to receive an ArrayStoreException at runtime if you try to assign the wrong type of object to an array element. For example:

    String [] strings = new String [10];
    Object [] objects = strings;  // alias String [] as Object []
    objects[0] = new Date(); // Runtime ArrayStoreException!

Here, we have “aliased” a String [] by assigning it to an Object []. By the third line, the compiler no longer knows the actual type of array stored in the object’s variable and has no choice but to let us try whatever we want. Of course, at runtime the VM realizes that we are trying to put a Date object into an array of Strings and throws the ArrayStoreException for us. This type of problem shouldn’t happen often for you in straightforward array use. We mention it here because the concept will come up again when we talk about generics in Chapter 8.

Get Learning Java, 4th Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.