泛型常見面試題

1. Java中的泛型是什麼 ? 使用泛型的好處是什麼?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. 如何編寫一個泛型方法,讓它能接受泛型參數並返回泛型類型?spa

編寫泛型方法並不困難,你須要用泛型類型來替代原始類型,好比使用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; //compilation error incompatible types

9. Array中能夠用泛型嗎?

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

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

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

List<String> rawList = new ArrayList()

注意: Hello.java使用了未檢查或稱爲不安全的操做;

這種警告可使用@SuppressWarnings(「unchecked」)註解來屏蔽。

Java泛型面試題補充更新:

我手頭又拿到了幾個Java泛型面試題跟你們分享下,這幾道題集中在泛型類型和原始類型的區別上,以及咱們是否能夠用Object來代替限定通配符的使用等等:

Java中List<Object>和原始類型List之間的區別?

原始類型和帶參數類型<Object>之間的主要區別是,在編譯時編譯器不會對原始類型進行類型安全檢查,卻會對帶參數的類型進行檢 查,經過使用Object做爲類型,能夠告知編譯器該方法能夠接受任何類型的對象,好比String或Integer。這道題的考察點在於對泛型中原始類 型的正確理解。它們之間的第二點區別是,你能夠把任何帶參數的類型傳遞給原始類型List,但卻不能把List<String>傳遞給接受 List<Object>的方法,由於會產生編譯錯誤。更多詳細信息請參閱Java中的泛型是如何工做的。

Java中List<?>和List<Object>之間的區別是什麼?

這道題跟上一道題看起來很像,實質上卻徹底不一樣。List<?> 是一個未知類型的List,而List<Object> 實際上是任意類型的List。你能夠把List<String>, List<Integer>賦值給List<?>,卻不能把List<String>賦值給 List<Object>。     

List<?> listOfAnyType;

List<Object> listOfObject = new ArrayList<Object>();

List<String> listOfString = new ArrayList<String>();

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

listOfAnyType = listOfString; //legal

listOfAnyType = listOfInteger; //legal

listOfObjectType = (List<Object>) listOfString; //compiler error – in-convertible types

想了解更多關於通配符的信息請查看Java中的泛型通配符示例

List<String>和原始類型List之間的區別.

該題相似於「原始類型和帶參數類型之間有什麼區別」。帶參數類型是類型安全的,並且其類型安全是由編譯器保證的,但原始類型List卻不是類型安全 的。你不能把String以外的任何其它類型的Object存入String類型的List中,而你能夠把任何類型的對象存入原始List中。使用泛型的 帶參數類型你不須要進行類型轉換,可是對於原始類型,你則須要進行顯式的類型轉換。

List listOfRawTypes = new ArrayList();

listOfRawTypes.add(「abc」);

listOfRawTypes.add(123); //編譯器容許這樣 – 運行時卻會出現異常

String item = (String) listOfRawTypes.get(0); //須要顯式的類型轉換

item = (String) listOfRawTypes.get(1); //拋ClassCastException,由於Integer不能被轉換爲String

List<String> listOfString = new ArrayList();

listOfString.add(「abcd」);

listOfString.add(1234); //編譯錯誤,比在運行時拋異常要好

item = listOfString.get(0); //不須要顯式的類型轉換 – 編譯器自動轉換

這些都是Java泛型面試中 頻繁出現的問題及其答案。全部這些面試題都不困難,其實它們都是基於泛型的基礎知識。任何對泛型有不錯了解的Java程序員都確定熟知這些泛型題目。若是 你有任何好的面試題,不論是在什麼面試中碰到的,或者若是你想知道任何Java泛型面試題的答案。

相關文章
相關標籤/搜索