溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JDK5.0新特性的學習--泛型(上)

發布時間:2020-08-11 08:55:30 來源:ITPUB博客 閱讀:172 作者:xuehongliang 欄目:編程語言

沒有泛型的日子
所有的java類都源自java.lang.Object,這意味著所有的JAVA對象能轉換成Object。因此,在之前的JDK的版本中,很多集合框架的函數接受一個Object參數。所以,collections是一個能持有任何對象的多用途工具,但帶來了不良的后果。

舉個簡單的例子,在JDK 5.0的之前版本中,類List的函數add接受一個Object參數:

  1. publicboolean add(java.lang.Object element)


所以你能傳遞任何類型給add。這是故意這么設計的。否則,它只能傳遞某種特定的對象,這樣就會出現各種List類型,如,StringList, EmployeeList, AddressList等。
add通過Object傳遞能帶來好處,現在我們考慮get函數(返回List中的一個元素).如下是JDK 5之前版本的定義:

  1. public java.lang.Object get(int index) throws IndexOutOfBoundsException

get返回一個Object.不幸的事情從此開始了.假如你儲存了兩個String對象在一個List中:

  1. List stringList1 = new ArrayList();
  2. stringList1.add("Java 5");
  3. stringList1.add("with generics");

當你想從stringList1取得一個元素時,你得到了一個Object.為了操作原來的類型元素,你不得不把它轉換為String。

  1. String s1 = (String) stringList1.get(0);

但是,假如你曾經把一個非String對象加入stringList1中,上面的代碼會拋出一個ClassCastException. 有了泛型,你能創建一個單一用途的List實例.比如,你能創建一個只接受String對象的List實例,另外一個實例只能接受Employee對象.這同樣適用于集合框架中的其他類型.

泛型入門

像一個函數能接受參數一樣,一個泛型也能接受參數.這就是一個泛型經常被稱為一個參數化類型的原因.但是不像函數用()傳遞參數,泛型是用<>傳遞參數的.聲明一個泛型和聲明一個普通類沒有什么區別,只不過你把泛型的變量放在<>中.
比如,在JDK 5中,你可以這樣聲明一個java.util.List : List myList;
E 稱為類型變量.意味著一個變量將被一個類型替代.替代類型變量的值將被當作參數或返回類型.對于List接口來說,當一個實例被創建以后,E 將被當作一個add或別的函數的參數.E 也會使get或別的參數的返回值.下面是add和get的定義:

  1. boolean add E get(int index)

一個泛型在聲明或例示時允許你傳遞特定的類型變量: E.除此之外,如果E是個類,你可以傳遞子類;如果E是個接口,你可以傳遞實現接口的類;

  1. List numberList= new ArrayList();
  2. numberList.add(2.0);
  3. numberList.add(2);

-----------------------------譯者添加--------------------

那么mylist的add函數將接受一個String作為他的參數,而get函數將返回一個String.因為返回了一個特定的類型,所以不用類型轉化了。

根據慣例,我們使用一個唯一的大寫字目表示一個類型變量。為了創建一個泛型,你需在聲明時傳遞同樣的參數列表。比如,你要想創建一個ArrayList來操作String ,你必須把String放在<>中。如:

  1. List myList = new ArrayList();

再比如,java.util.Map 是這么定義的:

public interface Map

K用來聲明map鍵(KEY)的類型而V用來表示值(VALUE)的類型。put和values是這么定義的:

V put(K key, V value)
Collection values()

一個泛型不準直接的或間接的是java.lang.Throwable的子類。因為異常是在運行時拋出的,所以它不可能預言什么類型的異常將在編譯時拋出.
列表1的例子將比較List在JDK 1.4 和JDK1.5的不同

  1. publicclass GenericListTest {
  2. publicstaticvoid main(String[] args) {
  3. // in JDK 1.4
  4. List stringList1 = new ArrayList();
  5. stringList1.add("Java 1.0 - 5.0");
  6. stringList1.add("without generics");
  7. // cast to java.lang.String
  8. String s1 = (String) stringList1.get(0);
  9. System.out.println(s1.toUpperCase());
  10. // now with generics in JDK 5
  11. List stringList2 = new ArrayList();
  12. stringList2.add("Java 5.0");
  13. stringList2.add("with generics");
  14. // no need for type casting
  15. String s2 = stringList2.get(0);
  16. System.out.println(s2.toUpperCase());
  17. }
  18. }

在列表1中,stringList2是個泛型。聲明List告訴編譯器List的實例能接受一個String對象。當然,在另外的情況中,你能新建能接受各種對象的List實例。注意,當從List實例中返回成員元素時,不需要對象轉化,因為他返回的了你想要的類型,也就是String.

泛型的類型檢查(type checking)是在編譯時完成的.
最讓人感興趣的事情是,一個泛型是個類型并且能被當作一個類型變量。比如,你想你的List儲存lists of Strings,你能通過把List作為他的類型變量來聲明List。比如:

  1. List> myListOfListsOfStrings;

要從myList中的第一個List重新取得String,你可以這么用:

  1. String s = myListOfListsOfStrings.get(0).get(0);

下一個列表中的ListOfListsTest類示范了一個List(命名為listOfLists)接受一個String List作為參數。

  1. publicclass ListOfListsTest {
  2. publicstaticvoid main(String[] args) {
  3. List listOfStrings = new ArrayList();
  4. listOfStrings.add("Hello again");
  5. List> listOfLists = new ArrayList>();
  6. listOfLists.add(listOfStrings);
  7. String s = listOfLists.get(0).get(0);
  8. System.out.println(s); // prints "Hello again"
  9. }
  10. }


另外,一個泛型接受一個或多個類型變量。比如,java.util.Map有兩個類型變量s。第一個定義了鍵(key)的類型,第二個定義了值(value)的類型。下面的例子講教我們如何使用個一個泛型Map.

  1. publicclass MapTest {
  2. publicstaticvoid main(String[] args) {
  3. Map map = new HashMap();
  4. map.put("key1", "value1");
  5. map.put("key2", "value2");
  6. String value1 = map.get("key1");
  7. }
  8. }


在這個例子中,重新得到一個key1代表的String值,我們不需要任何類型轉換。



-----------------------------譯者添加--------------------

如果你傳遞一個String給一個List,比如:

List myList;[@more@]

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女