Main Page

Previous Next

Casting Objects

You can cast an object to another class type, but only if the current object type and the new class type are in the same hierarchy of derived classes, and one is a superclass of the other. For example, earlier in this chapter we defined the classes Animal, Dog, Spaniel, Cat and Duck, and these classes are related in the hierarchy shown below:

Click To expand

You can cast an object of a class upwards through its direct and indirect superclasses. For example, you could cast an object of type Spaniel directly to type Dog, type Animal or type Object. You could write:

Spaniel aPet = new Spaniel("Fang");
Animal theAnimal = (Animal)aPet;   // Cast the Spaniel to Animal

When you are assigning an object to a variable of a superclass type, you do not have to include the cast. You could write the assignment as:

Animal theAnimal = aPet;           // Cast the Spaniel to Animal

and it would work just as well. The compiler is always prepared to insert a cast to a superclass type when necessary.

When you cast an object to a superclass type, Java retains full knowledge of the actual class to which the object belongs. If this were not the case, polymorphism would not be possible. Since information about the original type of an object is retained, you can cast down a hierarchy as well. However, you must always write the cast explicitly since the compiler is not prepared to insert it, and the object must be a legitimate instance of the class you are casting to – that is, the class you are casting to must be the original class of the object, or must be a superclass of the object. For example, you could cast a reference stored in the variable theAnimal above to type Dog or type Spaniel, since the object was originally a Spaniel, but you could not cast it to Cat or Duck, since an object of type Spaniel does not have Cat or Duck as a superclass. To cast theAnimal to type Dog, you would write:

Dog aDog = (Dog)theAnimal;         // Cast from Animal to Dog

Now the variable aDog refers to an object of type Spaniel that also happens to be a Dog. Remember, you can only use the variable aDog to call the polymorphic methods from the class Spaniel that override methods that exist in Dog. You can't call methods that are not defined in the Dog class. If you want to call a method that is in the class Spaniel and not in the class Dog, you must first cast aDog to type Spaniel.

Although you cannot cast between unrelated objects, from Spaniel to Duck for instance, you can achieve a conversion by writing a suitable constructor but obviously, only where it makes sense to do so. You just write a constructor in the class to which you want to convert, and make it accept an object of the class you are converting from as an argument. If you really thought Spaniel to Duck was a reasonable conversion, you could add the constructor to the Duck class:

public Duck(Spaniel aSpaniel) {
   // Back legs off, and staple on a beak of your choice...
   super("Duck");           // Call the base constructor
   name = aSpaniel.getName();
   breed = "Barking Coot";  // Set the duck breed for a converted Spaniel

This assumes you have added a method, getName(), in the class Dog which will be inherited in the class Spaniel, and which returns the value of name for an object. This constructor accepts a Spaniel and turns out a Duck. This is quite different from a cast though. This creates a completely new object that is separate from the original, whereas a cast presents the same object as a different type.

When to Cast Objects

You will have cause to cast objects in both directions through a class hierarchy. For example, whenever you execute methods polymorphically, you will be storing objects in a variable of a base class type, and calling methods in a derived class. This will generally involve casting the derived class objects to the base class. Another reason you might want to cast up through a hierarchy is to pass an object of several possible subclasses to a method. By specifying a parameter as base class type, you have the flexibility to pass an object of any derived class to it. You could pass a Dog, Duck or Cat to a method as an argument for a parameter of type Animal, for instance.

The reason you might want to cast down through a class hierarchy is to execute a method unique to a particular class. If the Duck class has a method layEgg(), for example, you can't call this using a variable of type Animal, even though it references a Duck object. As we have already said, casting downwards through a class hierarchy always requires an explicit cast.

Try It Out – Casting Down to Lay an Egg

We'll amend the Duck class and use it along with the Animal class in an example. Add layEgg() to the Duck class as:

public class Duck extends Animal {
  public void layEgg() {
    System.out.println("Egg laid");
   // Rest of the class as before...

If you now try to use this with the code:

public class LayEggs {
  public static void main(String[] args) {
    Duck aDuck = new Duck("Donald", "Eider");
    Animal aPet = aDuck;                    // Cast the Duck to Animal
    aPet.layEgg();                          // This won't compile!

you will get a compiler message to the effect that layEgg() is not found in the class Animal.

Since you know this object is really a Duck, you can make it work by writing the call to layEgg() in the code above as:

      ((Duck)aPet).layEgg();                  // This works fine

The object pointed to by aPet is first cast to type Duck. The result of the cast is then used to call the method layEgg(). If the object were not of type Duck, the cast would cause an exception to be thrown.


In general, you should avoid explicitly casting objects as much as possible, since it increases the potential for an invalid cast and can therefore make your programs unreliable. Most of the time you should find that if you design your classes carefully, you won't need explicit casts very often.

Identifying Objects

There are circumstances when you may not know exactly what sort of object you are dealing with. This can arise if a derived class object is passed to a method as an argument for a parameter of a base class type, for example, in the way we discussed in the previous section. In some situations you may need to cast it to its actual class type, perhaps to call a class specific method. If you try to make an illegal cast, an exception will be thrown, and your program will end, unless you have made provision for catching it. One way to obviate this situation is to test that the object is the type you expect before you make the cast.

We saw earlier in this chapter how we could use the getClass() method to obtain the Class object corresponding to the class type, and how we could compare it to a Class instance for the class we are looking for. You can also do this using the operator instanceof. For example, suppose you have a variable, pet, of type Animal, and you want to cast it to type Duck. You could code this as:

Duck aDuck;                      // Declare a duck 

if(pet instanceof Duck) {
  aDuck = (Duck)pet;             // It is a duck so the cast is OK
  aDuck.layEgg();                // and we can have an egg for tea

If pet does not refer to a Duck object, an attempt to cast the object referenced by pet to Duck would cause an exception to be thrown. This code fragment will only execute the cast and lay an egg if pet does point to a Duck object. The code fragment above could have been written much more concisely as:

if(pet instanceof Duck)
  ((Duck)pet).layEgg();          // It is a duck so we can have an egg for tea

So what is the difference between this and using getClass()? Well, it's quite subtle. The instanceof operator checks whether a cast of the object referenced by the left operand to the type specified by the right operand is legal. The result will be true if the object is the same type as the right operand, or of any subclass type. We can illustrate the difference by choosing a slightly different example.

Suppose pet stores a reference to an object of type Spaniel. We want to call a method defined in the Dog class so we need to check that pet does really reference a Dog object. We can check for whether or not we have a Dog object with the statements:

if(pet instanceof Dog)
  System.out.println("We have a dog!");
  System.out.println("It's definitely not a dog!");

We will get confirmation that we have a Dog object here even though it is actually a Spaniel object. This is fine though for casting purposes. As long as the Dog class is in the class hierarchy for the object, the cast will work OK, so the operator is telling us what we need to know. However, suppose we write:

if(pet.getClass() == Dog.class)
  System.out.println("We have a dog!");
  System.out.println("It's definitely not a dog!");

Here the if expression will be false because the class type of the object is Spaniel, so its Class object is different from that of Dog.class – we would have to write Spaniel.class to get the value true from the if expression.

We can conclude from this that for casting purposes you should always use the instanceof operator to check the type of a reference. You only need to resort to checking the Class object corresponding to a reference when you need to confirm the exact type of the reference.

Previous Next
JavaScript Editor Java Tutorials Free JavaScript Editor