Daniel Chirillo said:
I don't know enough about the internals to give you a complete answer.
I'll let someone else provide more details.
Here's what I've noticed: Although the compiler will allow you to
downcast arrays, you will always get a ClassCassException if you
downcast an array.
/snip/
Wrong.
{
String[] sa;
Object[] oa;
sa = new String[1];
sa[0] = "Fubar";
oa = (Object[]) sa; /* upcast OK */
sa = (String[]) oa; /* downcast OK */
}
That's an example that won't get ClassCastException.
The actual component type of the array when the array
was created determines how far down you can cast an
Object[].
If you created an Object[], then you're stuck with
that. If you created a String[], then you can cast
back-and-forth between Object[] and String[].
You cannot cast downward any deeper than the
original array element type that was specified
when the array was created. It doesn't matter
whether the actual instances in the array have
deeper sub-types or whether they could all be
downcast successfully to a deeper sub-type.
public class A {}
public class B extends A {}
{
B[] ba;
A[] aa;
aa = new A[1];
aa[0] = new B(); /* sub-type of A */
ba = (B[]) aa; /* downcast: ClassCastException */
}
The ClassCastException above occurs due to
the array element type is A, not B, even
though every element instance of the array
is type B.
This is all specified in the JLS. An array has
its own type and its own rules for downcasting
that are separate from the rules for downcasting
the individual element instances.
Hope this helps.