Ответ 1
Я уверен, что вы не можете использовать в цикле, как хотите.
Мне было интересно, возможно ли его напрямую подвергать объектам внутри цикла foreach.
Мы имеем следующие два класса: один из них расширяет другой:
class Book {};
class ExtendedBook extends Book {};
Теперь у нас есть массив книг, которые я хочу пропустить, потому что его поиск в расширенной книге я уверен, что все книги на самом деле являются расширенными. Есть ли способ напрямую их бросить?
Book [] books = bookSearch.getBooks("extendedBooks");
for (Book book: books){
ExtendedBook eBook = (ExtendedBook) book;
....
}
Это включает два шага. Сначала зацикливайтесь на книгах и на втором шаге бросаете их. Можно ли сделать это за один шаг?
Что не работает:
// 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){}
Я знаю, что это не настоящая боль, но сохранение цикла короче было бы приятным и, возможно, более читаемым, поскольку вы сохраняете фиктивную переменную, которая просто используется для кастинга вместо фактического действия.
Я уверен, что вы не можете использовать в цикле, как хотите.
Как использовать дженерики?
Напишите свою подпись в качестве:
<B extends Book> B [] getBooks(Class<B> bookType)
Теперь, если вы хотите искать книги типа ExtendedBook
, просто вызовите:
ExtendedBooks [] eBooks = bookSearch.getBooks(ExtendedBook.class)
Не требуется никаких типов или других небезопасных вещей. Приятный и чистый.
Конечно, вам все равно нужно убедиться, что только ExtendedBook
возвращает только такую книгу, но похоже, что вы уже это решили.
Подумайте о том, как отличить
ExtendedBook ex=(ExtendedBook)new Book();
Это принято компилятором, но JVM выбрасывает java.lang.ClassCastException
, потому что этот тип кастинга неверен → Book
не ExtendedBook
, поэтому есть вероятность, что он не обработает потенциальные новые методы, добавленные в ExtendedBook
класс.
По той же причине вы не можете сделать что-то вроде
ExtendedBook[] exbooksB=(ExtendedBook[]) new Book[10];
но может
Book[] booksA=new ExtendedBook[10];
ExtendedBook[] exbooks=(ExtendedBook[]) booksA;
Вы не можете, потому что java не поддерживает неявную перегрузку преобразования, как в С#, с неявным оператором.