Downcasting in Java Downcasting in Java java java

Downcasting in Java


Downcasting is allowed when there is a possibility that it succeeds at run time:

Object o = getSomeObject(),String s = (String) o; // this is allowed because o could reference a String

In some cases this will not succeed:

Object o = new Object();String s = (String) o; // this will fail at runtime, because o doesn't reference a String

When a cast (such as this last one) fails at runtime a ClassCastException will be thrown.

In other cases it will work:

Object o = "a String";String s = (String) o; // this will work, since o references a String

Note that some casts will be disallowed at compile time, because they will never succeed at all:

Integer i = getSomeInteger();String s = (String) i; // the compiler will not allow this, since i can never reference a String.


Using your example, you could do:

public void doit(A a) {    if(a instanceof B) {        // needs to cast to B to access draw2 which isn't present in A        // note that this is probably not a good OO-design, but that would        // be out-of-scope for this discussion :)        ((B)a).draw2();    }    a.draw();}


I believe this applies to all statically typed languages:

String s = "some string";Object o = s; // okString x = o; // gives compile-time error, o is not neccessarily a stringString x = (String)o; // ok compile-time, but might give a runtime exception if o is not infact a String

The typecast effectively says: assume this is a reference to the cast class and use it as such. Now, lets say o is really an Integer, assuming this is a String makes no sense and will give unexpected results, thus there needs to be a runtime check and an exception to notify the runtime environment that something is wrong.

In practical use, you can write code working on a more general class, but cast it to a subclass if you know what subclass it is and need to treat it as such. A typical example is overriding Object.equals(). Assume we have a class for Car:

@Overrideboolean equals(Object o) {    if(!(o instanceof Car)) return false;    Car other = (Car)o;    // compare this to other and return}