10 道關於 Java 泛型的面試題

轉載自   10 道關於 Java 泛型的面試題

1.Java中的泛型是什麼 ? 使用泛型的好處是什麼?

這是在各種Java泛型面試中,一開場你就會被問到的問題中的一個,主要集中在初級和中級面試中。那些擁有Java1.4或更早版本的開發背景的人都知道,在集合中存儲對象並在使用前進行類型轉換是多麼的不方便。

泛型防止了那種情況的發生。它提供了編譯期的類型安全,確保你只能把正確類型的對象放入集合中,避免了在運行時出現ClassCastException。

  

2. Java的泛型是如何工作的 ? 什麼是類型擦除 ?

這是一道更好的泛型面試題。泛型是通過類型擦除來實現的,編譯器在編譯時擦除了所有類型相關的信息,所以在運行時不存在任何類型相關的信息。例如List<String>在運行時僅用一個List來表示。這樣做的目的,是確保能和Java 5之前的版本開發二進制類庫進行兼容。

你無法在運行時訪問到類型參數,因爲編譯器已經把泛型類型轉換成了原始類型。根據你對這個泛型問題的回答情況,你會得到一些後續提問,比如爲什麼泛型是由類型擦除來實現的或者給你展示一些會導致編譯器出錯的錯誤泛型代碼。更多請參考這篇文章《揭開Java 泛型類型擦除神祕面紗》。

 

3. 什麼是泛型中的限定通配符和非限定通配符 ?

這是另一個非常流行的Java泛型面試題。限定通配符對類型進行了限制。有兩種限定通配符,一種是<? extends T>它通過確保類型必須是T的子類來設定類型的上界,另一種是<? super T>它通過確保類型必須是T的父類來設定類型的下界。泛型類型必須用限定內的類型來進行初始化,否則會導致編譯錯誤。另一方面<?>表示了非限定通配符,因爲<?>可以用任意類型來替代。

  

4. List<? extends T>和List <? super T>之間有什麼區別 ?

這和上一個面試題有聯繫,有時面試官會用這個問題來評估你對泛型的理解,而不是直接問你什麼是限定通配符和非限定通配符。這兩個List的聲明都是限定通配符的例子,List<? extends T>可以接受任何繼承自T的類型的List,而List<? super T>可以接受任何T的父類構成的List。例如List<? extends Number>可以接受List<Integer>或List<Float>。在本段出現的連接中可以找到更多信息。

 

5. 如何編寫一個泛型方法,讓它能接受泛型參數並返回泛型類型?

編寫泛型方法並不困難,你需要用泛型類型來替代原始類型,比如使用T, E or K,V等被廣泛認可的類型佔位符。泛型方法的例子請參閱Java集合類框架。最簡單的情況下,一個泛型方法可能會像這樣:

public V put(K key, V value) {

 return cache.put(key, value);

}

   

6. Java中如何使用泛型編寫帶有參數的類?

這是上一道面試題的延伸。面試官可能會要求你用泛型編寫一個類型安全的類,而不是編寫一個泛型方法。關鍵仍然是使用泛型類型來代替原始類型,而且要使用JDK中採用的標準佔位符。

 

7. 編寫一段泛型程序來實現LRU緩存?

對於喜歡Java編程的人來說這相當於是一次練習。給你個提示,LinkedHashMap可以用來實現固定大小的LRU緩存,當LRU緩存已經滿了的時候,它會把最老的鍵值對移出緩存。

LinkedHashMap提供了一個稱爲removeEldestEntry()的方法,該方法會被put()和putAll()調用來刪除最老的鍵值對。當然,如果你已經編寫了一個可運行的JUnit測試,你也可以隨意編寫你自己的實現代碼。

 

8. 你可以把List<String>傳遞給一個接受List<Object>參數的方法嗎?

對任何一個不太熟悉泛型的人來說,這個Java泛型題目看起來令人疑惑,因爲乍看起來String是一種Object,所以List<String>應當可以用在需要List<Object>的地方,但是事實並非如此。真這樣做的話會導致編譯錯誤。

如果你再深一步考慮,你會發現Java這樣做是有意義的,因爲List<Object>可以存儲任何類型的對象包括String, Integer等等,而List<String>卻只能用來存儲Strings。 

List<Object> objectList; 
List<String> stringList;
objectList = stringList;

 

9. Array中可以用泛型嗎?

這可能是Java泛型面試題中最簡單的一個了,當然前提是你要知道Array事實上並不支持泛型,這也是爲什麼Joshua Bloch在Effective Java一書中建議使用List來代替Array,因爲List可以提供編譯期的類型安全保證,而Array卻不能。

 

10. 如何阻止Java中的類型未檢查的警告?

如果你把泛型和原始類型混合起來使用,例如下列代碼,Java 5的javac編譯器會產生類型未檢查的警告,例如  

List<String> rawList = new ArrayList();

更多面試題及答案請在後臺回覆:面試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章