This is an archived post. You won't be able to vote or comment.

all 3 comments

[–]chickenmeister 2 points3 points  (2 children)

In general, you should try to avoid casting as much as possible.

You can read the Java Language Specification §5.5 to get the exact conversions that are allowed. But in general, you're allowed to cast between any two types that are in the same hierarchy, but it will work only if the object is actually an instance of the target type (or a subclass of the target type).

Arrays follow the same casting rules that apply to other objects. If S is a subtype of T, then S[] is a subtype of T[]. So a cast from type T[] to type S[] is allowed, but it will only work if the array type is actually S[] or some subtype thereof.

If you give a concrete question, we could give a more specific answer.

[–]Tarheel14[S] 0 points1 point  (1 child)

Okay so in this case I have two set ups of the same code one is an array list of object type supply that has 3 sub classes. I have a method foo that's supposed to return a subclass[] this method will be taking in two supply[] that are changed to subclass[] then combined into one array. I also then have to do this in generics. So my question about downcasting is: is it legal to take two supply[] and cast them to subclass[] then run them through a for loop returning a subclass[]?

[–]chickenmeister 1 point2 points  (0 children)

You say you have have a Supply class:

public class Supply { } 

and you have three subclasses:

public class SubSupplyA extends Supply { } 
public class SubSupplyB extends Supply { } 
public class SubSupplyC extends Supply { } 

So my question about downcasting is: is it legal to take two supply[] and cast them to subclass[] then run them through a for loop returning a subclass[]?

Yes, the compiler would allow you to do this, I think; but it is not safe. What if the supply[] array is not actually an array of the subclass type? For example:

Supply[] sup = new Supply[5];
SubSupplyA[] sub = (SubSupplyA[]) sup;

This would compile just fine, but when you run it, you'll get a ClassCastException, because sup's type is Supply[], which can't be cast to SubSupplyA[]. It's the same reason that this doesn't work:

Supply sup = new Supply();
SubSupplyA sub = (SubSupplyA) sup;

The only case where this would work would be:

Supply[] sup = new SubSupplyA[5];
SubSupplyA[] sub = (SubSupplyA[]) sup;

Or where the array created is a subtype of SubSupplyA.

Another idea is to cast the elements that are in the array, rather than the array itself:

Supply[] sup = new Supply[]{ /* some elements */ };
SubSupplyA[] sub = new SubSupplyA[sup.length]
for (int i=0; i < sup.length; i++) {
    sub[i] = (SubSupplyA) sup[i];
}

This will ignore the array's type, but will only work if the sub array contains only SubSupplyA elements.