为什么类型转换失败但在构造函数之后工作正常



我正在探索Java,在尝试类型转换时,我遇到了以下问题,当我第一次调用该方法时,转换失败了,但在构造列表后,它工作得很好。

寻找一个明确的解释,请:)由于

import java.util.*;
import java.util.Set;
import java.util.HashMap; // import the HashMap class

public class Main{     
public static void main(String[] args)     
{     
Set<Map<String, ?>> rows = new HashSet();

HashMap<String, String> map = new HashMap<String, String>();
map.put("1","one");
map.put("2","two");

HashMap<String, String> mapp = new HashMap<String, String>();
mapp.put("3","three");
mapp.put("4","four");

rows.add(map);
rows.add(mapp);
//WHY THE FOLLOWING DOESN'T WORK ?????
//printItems((List<Map<String, ?>>) rows);

//BUT THE FOLLOWING WORKS FINE
List<Map<String, ?>> listedRows = new ArrayList<>(rows);
printItems(listedRows);
}

public static void printItems(List<Map<String, ?>> items) {
for (Map<String, ?> str: items)
System.out.println(str);
}
}    

不能工作,因为rows的运行时类型是HashSet,HashSet不实现List接口。

当你创建listedRows时,它可以工作,因为该对象的运行时类型是ArrayList,它实现了List接口。

在您的示例中,您可以只在printItems中使用Collection抽象,因为您所需要做的就是遍历项。这将允许您使用SetList(或任何其他Collection)调用该方法,而无需强制转换或重新创建对象。

public static void printItems(Collection<Map<String, ?>> items) {
for (Map<String, ?> str: items)
System.out.println(str);
}

如果你感兴趣的话:

强制类型转换通常只在下列情况下起作用:编译时类型的对象是运行时类型的父类,并且需要将对象的编译时类型强制转换为运行时类型,以便调用特定于运行时类型的方法。

例如:

public void addTenObjects(List l) {
if (l instanceof ArrayList)
((ArrayList)l).ensureCapacity(10)

for (int i = 0; i < 10; i++) 
l.add(new Object())
}

SetList接口都扩展了Collection,但它们之间不相互扩展。也就是说,它们是同胞,因此你不能通过强制转换将一个转换为另一个。

由于您的方法printItems只是打印传入它的参数的内容,您可以使用Java 8Iterable.forEach()代替它,它期望一个Consumer表示动作:

rows.forEach(System.out::println);

不需要类型强制转换或复制任何东西,当您有一个相当简单的逻辑(如本例)时,也不需要引入该方法。

相关内容

  • 没有找到相关文章

最新更新