簡體   English   中英

Java通用列表返回類型

[英]Java generic list return type

我在使用返回通用列表的方法時遇到了一些問題。 代碼基本上是這樣的:

public class MyClass{
    private List<MyListElement> myList = new ArrayList<MyListElement>();

    public <E> List<E> getGenericList(){
        return new ArrayList<E>();
    }

    public void thisWorks(){
        List<MyListElement> newList = getGenericList();
        myList.addAll(newList);
    }

    public void thisDoesntWork(){
        myList.addAll(getGenericList());
    }

    public void thisDoesntWorkEither(){
        for(MyListElement elem : getGenericList()){
            fiddle();
        }
    }
}

為什么thisDoesntWork()方法不起作用,還有其他任何方法(除了做這個並不總是實用的thisWorks()方法)?

編譯器無法推斷在thisDoesntWork()中為泛型方法getGenericList()的類型參數<E>選擇的類型。

在這種情況下,您需要通過調用<MyListElement>getGenericList()顯式聲明type參數的Type

或者,您可以更改getGenericList()的簽名以接受Class<E>參數。 然后你將在thisWorks()thisDoesntWork()調用getGenericList(MyListElement.class) thisDoesntWork() 不可否認,這有點冗長,但對於您的方法的客戶來說絕對更直觀。

我會說,作為一般規則,嘗試使泛型方法的類型參數可以從該方法的參數中推斷出來。

您可以像這樣更改thisDoesntWork()

  public void thisDoesntWork(){ // well, it works now
      myList.addAll(this.<String>getGenericList());
  }

您需要告訴編譯器getGenericList()正在處理什么類型。

泛型方法<E> getGenericsList()的類型參數可以在調用時傳遞:

this.<String>getGenericsList()

否則編譯器會盡力從上下文中推斷出它。 將返回的對象分配給List<String>引用時,編譯器因此推斷您將String作為類型參數傳遞。

鑒於List API

List<E> {
  void addAll(Collection<? extends E> c);
}

編譯器似乎無法推斷出正確的類型,說實話我不知道這是因為它不夠智能,還是因為它不想通過設計承擔責任

我甚至做了一個測試,看看問題是否是通配符,或者addAll()是否無法從參數化類型推斷出類型參數,但似乎沒有任何效果:

public class GenericsList {

    public static void main(String[] args) {
        // same signature as Java API
        List<String> base = new List<String>();
        base.addAll(GenericsList.getList()); // ERROR!

        // addAll() doesn't use a wildcard
        List2<String> base2 = new List2<String>();
        base2.addAll(getList2()); // ERROR!

        // what about a generic method?
        addAll(base, getList()); // ERROR!
    }

    static <E> List<E> getList() {
        return new List<E>();
    }

    static <E> void addAll(List<E> src, List<E> other) {}

    static <E> List2<E> getList2() {
        return new List2<E>();
    }

    static class List<E> {
        void addAll(List<? extends E> other) {}
    }

    static class List2<E> {
        void addAll(List2<E> other) {}
    }

}

此代碼適合您。 getGenericList()應該知道它返回的內容,並且應該與列表類型兼容。

您不需要將其轉換為String或其他人建議的任何其他內容,因為它會通過將其綁定到字符串類型來限制您的getGenericList方法意圖。

public class MyClass{
    private List<MyListElement> myList = new ArrayList<MyListElement>();

    public <E extends MyListElement> List<E> getGenericList(){
        return new ArrayList<E>();
    }

    public void thisWorks(){
        List<MyListElement> newList = getGenericList();
        myList.addAll(newList);
    }

    public void thisDoesntWork(){
        myList.addAll(getGenericList());
    }

    public void thisDoesntWorkEither(){
        for(MyListElement elem : getGenericList()){
            fiddle();
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM