I added one more subclass of in my explanation.
Tree
/ \
/ \
/ \
Redwood Blackwood
In this hierarchy:
Upcast:
When we cast a reference along the class hierarchy in a direction from the sub classes towards the root
. We need not use a cast operator in this case
Upcase Example:
A Redwood
or Blackwood
both are tree
: So
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = b; // Valid
Downcast:
When we cast a reference along the class hierarchy in a direction from the root class towards the children or subclasses
. We need explicitly type cast.
Downcast Example:
Redwood r = new Tree(); //compiler error, because Tree is not a Redwood
Blackwood r = new Tree(); //compiler error, because Tree is not a Blackwood
You need to explicitly type cast a Tree object
if it really points to either Redwood
or Blackwook
object, other wise it error at runtime. e.g.
in this case:
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = r; // Valid
Redwood r2 = (Redwood)t1;
Blackwood b2 = (Blackwood)t2
[ANSWER]
Redwood r = (Redwood) new Tree();
why no compiler error?
its example of Downcast:
source Redwood r = (Redwood) new Tree();
fist create Tree object and typecast to Redwood
.
you can think this as follows:
Tree t = new Tree();`
Redwood r = (Redwood)t;
So its ok at compile-time,
[ANSWER]
Why Runtime error?
But really Redwood
subclass can't point to Tree
supper class object. so your code fails at runtime.
Tree t = new Tree();
t
points to Tree()
object not Redwood()
. that's the reason of runtime error.
Compiler do not now what is value in t
and syntactically every thing is write. But at run time due to Redwood r = (Redwood)t;
, where t
is a object of Tree class
if became faulty.
[SUGGESTION:]
I would like to suggest you to use instanceof operator:
The casting/coercing operation is used to convert between types and the instanceof operator is used to check for type information at run time.*
Description:
The instanceof operator allows you determine the type of an object. It takes an object on the left side of the operator and a type on the right side of the operator and returns a boolean value indicating whether the object belongs to that type or not. This is most clearly demonstrated with an example:
if (t instanceof Redwood)
{
Redwood r = (Redwood)t;
// rest of your code
}
But I would also add: Casting from a base type to a derived type is a bad thing.
Reference: Beware of instanceof operator