搜尋

首頁  >  問答  >  主體

java 泛型的问题

我想写一个方法list->array 想利用泛型,代码如下

public static <T> T[] list2Array(List<T> list){
    T[] array = (T[])list.toArray(new T[list.size()]);
    return array;
}

也就是传过来的String就返回String数组 Integer就返回Integer数组。但是这个new T[list.size]这里有问题,请问怎么解决?谢谢。

天蓬老师天蓬老师2788 天前580

全部回覆(3)我來回復

  • PHP中文网

    PHP中文网2017-04-17 11:24:00

    這個Effective Java第二版裡有說到, Item25.

    Because of these fundamental differences, arrays and generics do not
    mix well. For example, it is illegal to create an array of a generic
    type, a parameterized type, or a type parameter. None of these array
    creation expressions are legal: new List[], new List[], new
    E[]. All will result in generic array creation errors at compile time.

    Generally speaking, arrays and generics don’t mix well. If you find
    yourself mixing them and getting compile-time errors or warnings, your
    first impulse should be to replace the arrays with lists.

    1. 因為數組和泛型不對付, 所以在不做強制類型轉換的情況下, 我們是沒有辦法得到一個泛型數組的實例的, 編譯器會限制此類情況發生(new E[], list .toArray());
    2. 為什麼陣列和泛型不對付, Effective Java裡面有例子. 根本原因在於:

    Arrays are covariant. This scary-sounding word means simply that if
    Sub is a subtype of Super, then the array type Sub[] is a subtype of
    Super[].

    給出例子說明我的理解, 類似的程式碼, 在泛型集合下, 會在靜態編譯階段報錯; 而泛型數組在運行階段給出ArrayStoreException:

    private <T> void doSomethingToGenArr(T[] tArr){
        Object[] oArr = tArr;
        oArr[0] = new String("aaa");
    }
    
    private <T> void doSomethingToGenList(List<T> list){
        List<Object> l1 =  list; /* compile error */
        l1.set(0, new String("aaa"));
    }
    
    @Test
    public void test111(){
        doSomethingToGenArr(new Integer[2]);
    }
    
    @Test
    public void test112(){
        doSomethingToGenList(new ArrayList<Integer>());
    }
    

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 11:24:00

    沒有泛型數組,這一說

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 11:24:00

    toArray()方法有兩種,帶參和不帶參.
    帶參的情況下,參數就是一個泛型數組,如T[] a,相當於你手動構造一個數組,傳入方法中.
    toArray()內部是一個copy的實現.

    舉兩個例子.
    1:String[][] str_a = (String [][]) arr.toArray(new String[0][0]);

    2 :String[][] a = new String[<size>][size];
    String [][] str_a = (String [][]) arr.toArray(a);

    當然 要保證轉型成功,不然會引發ClassCastException.

    --------------------------分割線------------------- ------

    以下是原始碼中是實作,其實就是一個copy操作.

     /**
         * Returns an array containing all of the elements in this list
         * in proper sequence (from first to last element).
         *
         * <p>The returned array will be "safe" in that no references to it are
         * maintained by this list.  (In other words, this method must allocate
         * a new array).  The caller is thus free to modify the returned array.
         *
         * <p>This method acts as bridge between array-based and collection-based
         * APIs.
         *
         * @return an array containing all of the elements in this list in
         *         proper sequence
         */
        public Object[] toArray() {
            return Arrays.copyOf(elementData, size);
        }
    

    回覆
    0
  • 取消回覆