2016-10-04 30 views
1

我当时正在玩泛型,现在我很好奇为什么我需要在E中添加“新Special()”之前将其添加到Set中。 我知道这是不是真的需要在这种情况下,因为我可以用一组基本的,以及...为什么我需要在使用有界类型参数时进行投射

private static class Base {} 
private static class Special extends Base{} 

private <E extends Base> Set<E> doSomething(){ 
    Set<E> someset = new HashSet<>(); 
    someset.add(new Special()); 
    return someset; 
} 
+0

的【什么是佩奇(生产者消费者扩展超)?(http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super) – user140547

+0

什么错误你可能的复制得到? – talex

回答

3

假设你有如下:

final class SomethingElse extends Base {} 

这:

private <E extends Base> doSomething(Set<E> someset) { 
    someset.add(new Special()); 
} 

你现在可以看到问题了吗?

E extends Base意味着 “E是延伸Base一个未知类型”。这并不意味着“E任何类型,延伸Base”。

在上面的例子中,问题是,一个可以称之为doSomething()这样的:

Set<Special> onlySpecials = new HashSet<>(); 
doSomething(onlySpecials); 
onlySpecials.stream() 
    .findFirst() 
    .ifPresent(Special::someSpecializedMethod); /* Boom! ClassCastException! */ 
+0

明白了,谢谢! – Daniel

1

试想Base有两个亚型:SpecialVerySpecial。 你叫doSomething这样的:

Set<VerySpecial> set = doSomething(); 

在这种情况下,您set将包含Special实例,它是不是你所期望的,因为它的类型唐不允许这样。

相关问题