2014-09-22 25 views
1

我知道這個問題已經被提出,但我從另一個角度看待它。 對generic type for ArrayList of ArrayLists是什麼提供了答案。但是,我正在尋找最佳實踐並進行接口編程。然後我提出了以下三個選項。如何創建ArrayList的ArrayList,使其適合程序接口原理

問題:

  1. 爲什麼選項1是編譯錯誤?爲什麼轉換不能發生?

  2. 選項2或3中的哪一個是首選的?

  3. 在選項3爲什麼接口「List」出現在語句的右側?請爲此提供適當的答案。我需要了解這些嵌套的泛型定義。

    1) List<List<Integer>> arList1 = new ArrayList<ArrayList<Integer>>(); 
    2) List<ArrayList<Integer>> arList2 = new ArrayList<ArrayList<Integer>>(); 
    3) List<List<Integer>> arList3 = new ArrayList<List<Integer>>(); 
    

回答

2
  1. 此代碼:

    List<List<Integer>> arList1 = new ArrayList<ArrayList<Integer>>(); 
    

    是一個編譯錯誤,因爲List<List<Integer>>可以合法持有LinkedList<Integer>,但分配的右手邊不能。泛型不是協變的。 (見優秀article on generics by Brian Goetz。)

  2. 我更喜歡3,除非我想明確要求列表添加到arList2必須是ArrayList的實例。雖然這樣的要求很少,但它可能會出現。

  3. 在Java 7中,您不需要這樣做。你可以寫:

    List<List<Integer>> arList1 = new ArrayList<>(); 
    

    ,編譯器將在List<Integer>補上右側的泛型類型參數。對於Java 6及更早版本,您需要明確地爲構造函數調用提供一個通用參數,該參數與作業左側的泛型參數兼容。

0

選項1是編譯錯誤,因爲類型不兼容。事實上,您可以將不是ArrayListList分成List<List<Integer>>,但不能分成ArrayList<ArrayList<Integer>>。這就是爲什麼List出現在選項3的右側。

選項3是首選的,因爲它通過接口引用對象。見Joshua Bloch,Effective Java:Programming Language Guide,item 34.