Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Direct casting in foreach loop

I was wondering if its possible to directly cast objects within a foreach loop.

We have the following two classes were one extends the other:

class Book {};
class ExtendedBook extends Book {};

Now we have an array of Books which I want to loop through, because its a ExtendedBook search I'm sure that all Books are actually Extended Books. Is there a way to directly cast them?

Book [] books = bookSearch.getBooks("extendedBooks");

for (Book book: books){
   ExtendedBook eBook = (ExtendedBook) book;
   ....
}

This involves two steps. First looping through the books and at the second step casting them. Can one do it in one step?

What doesn't work:

// Directly assign it to a different type
for (ExtendedBook book : books){}

// Directly casting the array
ExtendedBooks [] eBooks = (ExtendedBooks []) books;

// Same goes for trying both in one step
for (ExtendedBook book : (ExtendedBook []) books){}

I know its not a real pain, but keeping the loop shorter would be nice and maybe more readable as you save a dummy variable, which is just used for casting instead of the actual action.

like image 822
Udo Held Avatar asked Jun 15 '12 11:06

Udo Held


2 Answers

How about using Generics?

Write your getBooks signature as:

<B extends Book> B [] getBooks(Class<B> bookType)

Now, if you want to search for books of the type ExtendedBook, just call:

ExtendedBooks [] eBooks = bookSearch.getBooks(ExtendedBook.class)

No typecasting or other unsafe stuff needed. Nice and clean.

Of course you still have to make sure that only ExtendedBook only returns that kind of book, but it looks like you solved that already.

like image 121
Gustav Karlsson Avatar answered Nov 07 '22 10:11

Gustav Karlsson


I'm reasonably sure you cannot cast in the loop as you would like.

like image 2
Miquel Avatar answered Nov 07 '22 10:11

Miquel