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.
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}