2016-10-04 72 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實例,它是不是你所期望的,因爲它的類型唐不允許這樣。

相關問題