2015-08-16 122 views
0

我想學習Java中的通配符。在這裏,我試圖修改printCollection方法,以便它只會使用延伸AbstractList的類。它顯示評論中的錯誤。我試圖用一個ArrayList的對象,它工作正常。我正在使用Java 7.ArrayList的對象和抽象

import java.util.AbstractList; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 
import java.util.Set; 

public class Subtype { 
    void printCollection(Collection<? extends AbstractList<?>> c) { 
     for (Object e : c) { 
      System.out.println(e); 
     } 
    } 

    public static void main(String[] args) { 
     Subtype st= new Subtype(); 
     ArrayList<String> al = new ArrayList<String>(); 
     al.add("a"); 
     al.add("n"); 
     al.add("c"); 
     al.add("f"); 
     al.add("y"); 
     al.add("w"); 
     //The method printCollection(Collection<? extends AbstractList<?>>) in the type Subtype is not applicable for the 
     // arguments (ArrayList<String>) 
     st.printCollection(al); 
    } 

} 
+0

是否有一個特定的原因,你爲什麼只希望允許列表擴展'AbstractList'而不是所有實現'List'接口(契約)的列表?通過指定'AbstractList',您可以將代碼耦合到特定的實現。只要有可能,你應該編碼到接口而不是實現。 –

+0

@MickMnemonic謝謝我會牢記這一點。 –

回答

2

您正在詢問AbstractList對象的集合,例如一個充滿AbstractLists的列表。這真的是你想要的嗎?

一個解決這將是這樣......

<T extends AbstractList<?>> void printCollection(T c) { 

......這樣一來,你的方法將只接受對象擴展AbstractLists任何通用內容。

但在其他評論者,海報和作家(布洛赫:有效的Jave,P134 +)已經正確地指出的那樣,更好的風格應該簡單地嘗試這樣的事:

void printCollection(AbstractList<?> c) { 
+0

謝謝你是對的,但我無法理解這是如何工作的 –

+0

我很抱歉,但我無法真正重複什麼需要一本好書頁面來解釋這裏。我建議引用一些Java泛型教程或書籍。 –

+0

我使用此鏈接閱讀有關通配符https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html –

2

在您的代碼你假設參數應實現Collection並應包含擴展AbstractList

void printCollection(Collection<? extends AbstractList<?>> c) 

元素要得到你想要的,你可以簡單地把它寫這樣的東西:

void printCollection(AbstractList<?> c) 
+1

我認爲這是一個更好的答案。如果可能,在方法簽名中使用有界通配符可以產生更靈活的API。 – scottb