Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast element in Java For Each statement

Is it possible (or even advisable) to cast the element retrieved from a for each statement in the statement itself? I do know that each element in list will be of type <SubType>.

I.E.:

List<BaseType> list = DAO.getList();  
for(<SubType> element : list){ 
    // Cannot convert from element type <BaseType> to <SubType>
    ...
}

rather than:

List <BaseType> list = DAO.getList();
for(<BaseType> el : list){
    <SubType> element = (<SubType>)el;
    ...
}
like image 721
Carl Summers Avatar asked Mar 19 '10 20:03

Carl Summers


3 Answers

Do you really know that each entry is going to be a subtype ? The DAO simply has to fulfill the List<BaseType> contract, and if you're assuming a subclass, then I think something is wrong somewhere. I'd perhaps concentrate more on getting the interface to the DAO correct, and have it contractually return what you want.

like image 115
Brian Agnew Avatar answered Sep 21 '22 15:09

Brian Agnew


For all the reasons stated by others, you shouldn't do this. However, if you cannot change the interface, the following is possible:

for (BaseType element : list) {
    SubType subType = (SubType)element;
    ...
}

As far as I know, this is the only way to do this and remain truly type safe - i.e. not rely on type erasure to catch any problems, which it will not necessarily do until much later.

I realize this is not EXACTLY what you were looking for, but it does handle the casting.

like image 41
aperkins Avatar answered Sep 17 '22 15:09

aperkins


It is in fact possible to combine the cast with the for loop, like so:

List<BaseType> list = DAO.getList();  
for (SubType subType : ((List<SubType>) list)){ 
    ...
}

Or you can use this slightly-cleaner pattern:

List<SubType> list = (List<SubType>) DAO.getList();  
for (SubType subType : list){ 
    ...
}

You will get an unchecked cast warning from the Java compiler, unless you suppress it. The effect of the first form will be effectively identical to casting each element within the loop. The second form will also enforce that new additions to the list must conform to SubType.

Note that this will NOT work with arrays, since arrays have distinct runtime types. In other words, BaseType[] is not castable to SubType[]. You can use the Arrays API to work around this, like so:

BaseType[] array = DAO.getArray();
for (SubType subType : Arrays.<SubType>asList(array)) {
    ...
}
like image 29
Peter Centgraf Avatar answered Sep 21 '22 15:09

Peter Centgraf