2016-09-25 34 views
0

我不能把握什麼是錯在這裏不兼容的類型:SomeX不能轉換到捕獲#1

import java.util.*; 

class Main { 
    private static class SomeX {} 

    void doSomethingWithX(SomeX someX) { 
     Collection<? extends SomeX> colectionOfX = new ArrayList<>(); 
     colectionOfX.add(someX); 
    } 
} 

javac說以下內容:

Main.java:8: error: method add in interface Collection<E> cannot be applied to given types; 
      colectionOfX.add(someX); 
        ^
    required: CAP#1 
    found: SomeX 
    reason: argument mismatch; SomeX cannot be converted to CAP#1 
    where E is a type-variable: 
     E extends Object declared in interface Collection 
    where CAP#1 is a fresh type-variable: 
     CAP#1 extends SomeX from capture of ? extends SomeX 

據我瞭解extends限制CAP#1的下限到SomeXSomeX本身應該滿足限制。

怎麼了? (編譯時javac 1.8.0_102

回答

0

如果你想允許colectionOfX包含的SomeX任何情況下,應該爲宣稱:

Collection<SomeX> colectionOfX = new ArrayList<>(); 

當你將它聲明爲

Collection<? extends SomeX> colectionOfX = ...; 

這意味着你可以爲其分配任何Collection,其中包含某種類型的元素,即SomeXSomeX的子類。

例如,您可以爲其指定List<SomeBX>,其中SomeBX延伸SomeX。在這種情況下,只能將SomeBX的實例添加到集合中。 因此,如果您嘗試將SomeX實例添加到非SomeBX(例如,SomeAX的一個實例,它也是SomeX的子類),它將無效。

+0

所以......所有這些都不回答「爲什麼我不能將SomeX'實例添加到'Collection <?extends SomeX>'」中的問題。該特定操作有什麼問題? –

+0

@XtraCoder正如我試圖解釋的那樣,'Collection <?擴展SomeX> colectionOfX'不接受'SomeX'的所有實例。即使你給它分配了'new ArrayList ()',你應該可以添加'SomeX'的任何實例,編譯器不能知道它,因爲它只依賴於編譯時類型,集<?擴展SomeX>'。 – Eran

0

所以,問題實際上已經在「How can I add to List<? extends Number> data structures?」中得到解答,但是谷歌搜索並沒有帶來這種匹配。

簡短的回答,據我得到它,低於:

class Main { 
    private static class SomeX {} 

    private static class SomeY extends SomeX {} 

    void doSomethingWithX(SomeX someX) { 
     Collection<? extends SomeX> colectionOfX = new ArrayList<SomeY>(); 
     colectionOfX.add(someX); 
    } 
} 

因爲<? extends SomeX>是相當的集合類型除項目類型束縛下限 - 這將是可以分配集合的實例與考慮到這一點,從編譯器的角度來看,將SomeX放入這樣的集合中並不是類型安全的。

相關問題