Suppose we have the following Java code in which a downcast is being performed:

class Parent{ /* ... */}

class ChildClass extends Parent { /* ... */ }

public class Tester {

     public static void main (String args[ ]) {
   
      Parent p = new Parent ( );
      
      /*this is a downcast since the Parent class
        object, "p" is being cast to a ChildClass type,
        and ChildClass derives from the Parent class */
      
      ChildClass c = (ChildClass) p; 

     }
}

Which of the following will happen with the code above:

1.  It will compile and run without any errors
2.  It will throw a compile time exception
3.  It will throw a Runtime exception

What is the definition of a downcast in Java?

It helps to first define exactly what a downcast is. It’s actually pretty simple – suppose you have a base class, and a class that derives from that base class either directly or indirectly. Then, anytime an object of that base class type is type cast into a derived class type, it is called a downcast. The reason it’s called a downcast is because of the way that inheritance diagrams are normally written – base classes are at the top and derived classes are down below the base classes. So, in downcasting, you are going down the inheritance diagram by taking an object of a base class (at the top), and then trying to convert into the type of one of the derived classes (going down). The key word there is trying – because downcasting does not always make sense depending on the code being written. In the code above, this line is where the downcast is being performed:

ChildClass c = (ChildClass) p; 

So, what happens when the code in our example above is run?

The code above will actually compile, but at runtime it will throw a Runtime Exception (a java.lang.ClassCastException).

If a Java expert would look at the code in our example up above, he or she would definitely know that the code would not work at run-time. So, why does it even compile? Well, remember that the compiler sees things differently from humans – and it thinks that the programmer knows what he is doing. But, in any case, the error is found at run time. By having the cast there (remember the cast is the “(ChildClass) p”), we are telling the compiler that we really do actually want to do this – it is not just a mistake in typing. So, the compiler trusts our judgement. But at runtime Java finds out that the object “p” is of the “ParentClass” type, and it will throw a Runtime Exception.

What if there was no type cast in the code above?

Suppose there is no type cast, and the critical line of code above is changed so that it looks like this:

ChildClass c =  p;

Then this code would give a compile time error instead of a runtime error – because there is no way that an object of the Parent class can ever be downcast to an object of it’s child class.

Is downcasting ever allowed in Java, and when would it be necessary?

Yes, downcasting is allowed in Java – if it wasn’t then the code up above would always return an error at compile time, not just at run-time. So, you might be wondering when exactly would it make sense to do a downcast – and that is a very good question. Downcasting is very useful when you need to compare one object to another. An example would help clarify – take a look at the code below:

public class Person
{
  private String name;
  private int age;

  public boolean equals(Object anObject)
  {
     if (anObject == null)
         return false;

     /* The object being passed in is checked
         to see it's class type which is then compared
         to the class type of the current class.  If they
         are not equal then it returns false
     */

     else if (getClass( ) != anObject.getClass())
         return false;

     else
     {
        /* 
         this is a downcast since the Object class
         is always at the very top of the inheritance tree
         and all classes derive either directly or indirectly 
         from Object:
        */
        Person aPerson = (Person) anObject;
        return ( name.equals(aPerson.name) 
                && (age == aPerson.age));
     }
  }

}

In the equals( ) method above, you can see that a downcast is being performed. The equals method is just comparing 2 objects to see if the name and age are equal in both objects. If so, it returns true. In the example above we have a Person class. Let’s also suppose that we also have some other classes that inherit or derive from the Person class – like AsianPerson, AmericanPerson, EuropePerson, etc. And, if we wanted to compare those classes to each other, then we would need an equals method like the one shown above. This method just accepts an object of type Object – because it needs to be able to accept any type of object.

Remember that in Java, every descendant of a class X is also of type X. This means that every descendant of the Person class is also of type Person. This is why downcasting would work if, in the equals method above, any object of a class type that is descended from Person is passed to the method. So, the equals method above is a great example of when downcasting is necessary and helpful – because it allows us to compare objects that are related via a common ancestor.

How to check to see if downcasting is valid and legitimate?

You can see that in the code above we run this:

else if (getClass( ) != anObject.getClass())
     return false;

The getClass() method allows us to get the class of the object being passed in and compare it to the class of the current class. If they are not equal then we don’t want to bother comparing them, and we know that the downcasting would be pointless.

Hiring? Job Hunting? Post a JOB or your RESUME on our JOB BOARD >>

Subscribe to our newsletter for more free interview questions.

7 thoughts on “Downcasting in Java”

WordPress › Error

There has been a critical error on your website.

Learn more about debugging in WordPress.