2017-07-19 88 views
5

我想了解泛型類型的用法,並且當我試驗一些代碼行時,我發現有些奇怪的東西。Java - 泛型類型和集合

的代碼的第一部分是一個名爲「A」類中:

public void func(int k, List list) { 
    list.add(9); 
    list.add(true); 
    list.add("a string"); 
    } 

代碼的第二部分是在不同的類,主要功能內:

List<Integer> arr = new ArrayList<Integer>(); 
     arr.add(14); 
     System.out.println(arr.toString()); 
     a.func(8, arr); 
     System.out.println(arr.toString()); 

運行被印刷在該行代碼的結果:

[14]

[14,9,真實,字符串]

這讓我很困惑,因爲arrInteger類型的ArrayList,怎麼可以包含boolean類型和String的對象?是否將函數func中的列表轉換爲原始類型(這意味着它變爲泛型類型Object)?如果是的話,怎麼可能,因爲你不能這樣做,例如:List<Integer> arr = new ArrayList<Object>();

想了解一下這個,也許它會幫助我更好地掌握泛型類型的這個主題。謝謝!

+0

你應該閱讀有關[RAW類型(https://docs.oracle.com/javase/tutorial/ java/generics/rawTypes.html)和[堆污染](https://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html#heap_pollution)。 – Flown

回答

1

Java不允許創建通用數組。 Java集合類主要使用Object數組實現。 ArrayList類可以看起來如下

public class ArrayList<T> implements List<T>, Serializable { 
    private transient Object[] data; 
    // more content... 
} 

在創建ArrayListObject[]陣列創建能夠容納任何類型的對象的新實例。 Typesafety只能通過使用泛型類型參數來實現。

因爲List沒有提供任何Type參數,所以它使用rawtype,任何東西都可以添加到列表中。因此,務必確保推斷模板參數以保持類型安全。

public void func(int k, List<Integer> list) { 
    list.add(9);  // works 
    list.add(true); // compile error 
    list.add("a string"); // compile error 
} 

您不應該使用rawtypes。根據您的編譯器設置,警告將被忽略。 最好使用(綁定/非綁定)通配符。

1

這類輸出的背後原因是要傳遞List作爲參數func(int k , List list) .列表FUNC方法是不通用的,它允許您添加字符串,以及使你得到這樣的輸出。

List<Integer> arr = new ArrayList<Integer>(); 
       arr.add(14); 
       System.out.println(arr.toString()); 
       a.func(8, arr); // here you are passing a list 
       System.out.println(arr.toString()); 

    public void func(List list) { // here List in non-generic 
     list.add(9); 
     list.add(true); 
     list.add("a string"); 
     } 
1

Java中的通用代碼的要點是在實際代碼編譯之前提供類型安全性。編譯的代碼沒有類型,這就是爲什麼我們在代碼中沒有遇到任何問題,因爲實際調用func()方法時,List arr沒有任何類型。

當我們打電話給System.out.println(arr.toString())時,我們只是在打印一個對象。這將罰款任何類型(即,int,布爾值,字符串等)。這就是爲什麼我們沒有遇到任何異常。

然而,僅僅嘗試分配從這個列表中的值,我們將java.lang.ClassCastException

... 
func(8, arr); 
System.out.println(arr.toString()); 
int a = arr.get(2);