2009-02-18 80 views
1

我編寫了這個簡單的測試代碼,通過調整一本書的內容來幫助我理解Java中泛型方法的工作。我標記的行是假設工作,爲什麼不是?通用方法失敗

import java.util.*; 

class Test { 
public static void main(String args[]){ 
    List<Number> input = null; 
    List<Number> output=null; 

    output = Test.process(input); // fail, why?? 

    } 
public static <E extends Number> List <? super E> process (List <E> nums){ 

    List <E>eList = new ArrayList<E>(); 
    return eList; 
    } 

} 

編輯:嗯,代碼改變List<? super E>List<E>時的作品,這是偉大的,但我仍然不知道我可能已經錯過了一些東西,或者如果我把這個從書中可能有錯誤。因爲它似乎有請閱讀問題:

  • 鑑於聲明的方法:
  • 公共靜態<é擴展號碼>列表 <?超級E>進程(名單NUMS)

    程序員想要使用此方法是這樣的:

    // INSERT DECLARATIONS HERE 
        output = process(input); 
    

    這對聲明可以被放置在// INSERT DECLARATIONS這裏允許 代碼編譯? (選擇所有適用的。)

    A. ArrayList<Integer> input = null; 
        ArrayList<Integer> output = null; 
    
    B. ArrayList<Integer> input = null; 
        List<Integer> output = null; 
    
    C. ArrayList<Integer> input = null; 
        List<Number> output = null; 
    
    D. List<Number> input = null; 
        ArrayList<Integer> output = null; 
    
    E. List<Number> input = null; 
        List<Number> output = null; 
    
    F. List<Integer> input = null; 
        List<Integer> output = null; 
    
    G. None of the above. 
    

    答案:B,E和F是正確的。 過程的返回類型肯定被聲明爲List而不是ArrayList,所以A和D 是錯誤的。 C是錯誤的,因爲返回類型的計算結果爲List<Integer>,而不能將 分配給List<Number>類型的變量。當然,所有這些可能會導致 NullPointerException,因爲變量仍然爲空 - 但問題只是要求我們 獲取代碼進行編譯。對書中提到的選項

    都沒有在我的代碼工作。我可以安全地將它標記爲Kathy Sierra的錯誤,還是我在這裏錯過了一些東西?

    回答

    7

    的問題是,你聲明你的方法的返回類型爲

    List<? super E>, i.e. List<? super Number> 
    

    但它所以,你要麼分配到

    List<Number> 
    

    將其分配給

    List<? super Number> 
    

    或聲明的返回類型爲

    List<E> i.e. List<Number> 
    

    (詳細格式,因爲內聯代碼沒有正確顯示泛型。)

    如果圖書權利要求分配方法的返回值的方式是可能你描述它然後確實在書中似乎是一個錯誤。如果該方法返回了E列表(如上所述),那將是正確的。

    1

    嘗試:

    import java.util.*; 
    
    class Test { 
    public static void main(String args[]){ 
        List<Number> input = null; 
        List<Number> output=null; 
    
        output = Test.process(input); // fail, why?? 
    
        } 
    public static <E extends Number> List <E> process (List <E> nums){ 
    
        List <E>eList = new ArrayList<E>(); 
        return eList; 
        } 
    
    } 
    
    +0

    也許你的代碼示例的簡短解釋? :) – 2009-02-18 03:24:00

    +0

    噢.. 你爲什麼拿走名單? – andandandand 2009-02-18 03:25:43

    0

    您的方法返回List。我們不知道它是什麼,但它絕對是一些超類Number的列表。例如:也許它返回了一個Object的列表 - 調用者不知道。但是,我們知道無論它是否返回List,都可以將Number加入其中。

    您正在將其分配給List of Number。這意味着只要你撥打output.get(n),你總是會收到Number

    看到問題了嗎? process()的返回值不符合output必須遵守的合同。