12

我想知道是否可以在 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){}

我知道这不是一个真正的痛苦,但是保持循环更短会很好,并且当您保存一个虚拟变量时可能更具可读性,该变量仅用于强制转换而不是实际操作。

4

5 回答 5

3

使用泛型怎么样?

将您的 getBooks 签名写为:

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

现在,如果您想搜索类型的书籍ExtendedBook,只需调用:

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

不需要类型转换或其他不安全的东西。干净整洁。

当然,您仍然必须确保ExtendedBook只返回那种书,但看起来您已经解决了这个问题。

于 2012-06-15T12:33:00.687 回答
2

我有理由确定您不能随心所欲地投入循环。

于 2012-06-15T11:54:24.987 回答
1

考虑铸造

ExtendedBook ex=(ExtendedBook)new Book();

它被编译器接受但 JVM throws java.lang.ClassCastException,因为这种类型的转换是错误的 -> Bookis not ExtendedBook,所以它有可能无法处理ExtendedBook类中添加的潜在新方法。

出于同样的原因,你不能做类似的事情

ExtendedBook[] exbooksB=(ExtendedBook[]) new Book[10];

但可以

Book[] booksA=new ExtendedBook[10];
ExtendedBook[] exbooks=(ExtendedBook[]) booksA;
于 2012-06-15T12:25:41.530 回答
0

你不能,因为 java 不支持隐式转换重载,就像在 C# 中使用隐式 operator一样。

于 2012-06-15T12:16:40.730 回答
0

你可以这样做。

Iterables.filter('Your array', the type class).forEach(x -> { } }

Iterables.filter(data, JSONObject.class).forEach(x -> { 
    x.getString("something") });    
于 2020-07-04T02:20:44.357 回答