国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

技術(shù)分析之——J2SE 5.0中的泛型

2019-11-18 11:54:33
字體:
供稿:網(wǎng)友

  摘要
  
  泛型是J2SE 5.0最重要的特性。他們讓你寫一個type(類或接口)和創(chuàng)建一個實例通過傳遞一個或多個引用類型。這個實例受限于只能作用于這些類型。比如,在java 5,java.util.List 已經(jīng)被泛化。當(dāng)建立一個list對象時,你通過傳遞一個java類型建立一個List實例,此list實例只能作用于所傳遞的類型。這意味著假如你傳遞一個String ,此List實例只能擁有String對象;假如你傳遞一個Integer,此實例只能存貯Integer對象。除了創(chuàng)建參數(shù)化的類型,你還能創(chuàng)建參數(shù)化的函數(shù)。
  
  泛型的第一個好處是編譯時的嚴(yán)格類型檢查。這是集合框架最重要的特點。此外,泛型消除了絕大多數(shù)的類型轉(zhuǎn)換。在JDK 5.0之前,當(dāng)你使用集合框架時,你不得不進行類型轉(zhuǎn)換。
  
  本文將教你如何操作泛型。它的第一部分是“沒有泛型的日子”,先讓我們回憶老版本JDK的不便。然后,舉一些泛型的例子。在討論完語法以及有界泛型的使用之后,文章最后一章將解釋如何寫泛型。
  
  沒有泛型的日子
  
  所有的java類都源自java.lang.Object,這意味著所有的JAVA對象能轉(zhuǎn)換成Object。因此,在之前的JDK的版本中,很多集合框架的函數(shù)接受一個Object參數(shù)。所以,collections是一個能持有任何對象的多用途工具,但帶來了不良的后果。
  
  舉個簡單的例子,在JDK 5.0的之前版本中,類List的函數(shù)add接受一個Object參數(shù):
  
  public boolean add(java.lang.Object element)
  
  所以你能傳遞任何類型給add。這是故意這么設(shè)計的。否則,它只能傳遞某種特定的對象,這樣就會出現(xiàn)各種List類型,如,StringList, EmployeeList, AddressList等。
  
  add通過Object傳遞能帶來好處,現(xiàn)在我們考慮get函數(shù)(返回List中的一個元素).如下是JDK 5之前版本的定義:
  
  public java.lang.Object get(int index) throws IndexOutOfBoundsException
  
  get返回一個Object.不幸的事情從此開始了.假如你儲存了兩個String對象在一個List中:
  
  List stringList1 = new ArrayList();stringList1.add("Java 5");stringList1.add("with generics");
  
  當(dāng)你想從stringList1取得一個元素時,你得到了一個Object.為了操作原來的類型元素,你不得不把它轉(zhuǎn)換為String。
  
  String s1 = (String) stringList1.get(0);
  
  但是,假如你曾經(jīng)把一個非String對象加入stringList1中,上面的代碼會拋出一個ClassCastException. 有了泛型,你能創(chuàng)建一個單一用途的List實例.比如,你能創(chuàng)建一個只接受String對象的List實例,另外一個實例只能接受Employee對象.這同樣適用于集合框架中的其他類型.
  
  泛型入門
  
  像一個函數(shù)能接受參數(shù)一樣,一個泛型也能接受參數(shù).這就是一個泛型經(jīng)常被稱為一個參數(shù)化類型的原因.但是不像函數(shù)用()傳遞參數(shù),泛型是用<>傳遞參數(shù)的.聲明一個泛型和聲明一個普通類沒有什么區(qū)別,只不過你把泛型的變量放在<>中.
  
  比如,在JDK 5中,你可以這樣聲明一個java.util.List : List<E> myList;
  
  E 稱為類型變量.意味著一個變量將被一個類型替代.替代類型變量的值將被當(dāng)作參數(shù)或返回類型.對于List接口來說,當(dāng)一個實例被創(chuàng)建以后,E 將被當(dāng)作一個add或別的函數(shù)的參數(shù).E 也會使get或別的參數(shù)的返回值.下面是add和get的定義:
  
  boolean add<E o>E get(int index)
  
  NOTE:一個泛型在聲明或例示時答應(yīng)你傳遞特定的類型變量: E.除此之外,假如E是個類,你可以傳遞子類;假如E是個接口,你可以傳遞實現(xiàn)接口的類;
  
  List<Number> numberList= new ArrayList<Number>();
  numberList.add(2.0);
  numberList.add(2);
  
  假如你傳遞一個String給一個List,比如:
  
  List<String> myList;
  
  那么mylist的add函數(shù)將接受一個String作為他的參數(shù),而get函數(shù)將返回一個String.因為返回了一個特定的類型,所以不用類型轉(zhuǎn)化了。
  
  NOTE:根據(jù)慣例,我們使用一個唯一的大寫字目表示一個類型變量。為了創(chuàng)建一個泛型,你需在聲明時傳遞同樣的參數(shù)列表。比如,你要想創(chuàng)建一個ArrayList來操作String ,你必須把String放在<>中。如:
  
  List<String> myList = new ArrayList<String>();
  
  再比如,java.util.Map 是這么定義的:
  
  public interface Map<K,V>
  
  K用來聲明map鍵(KEY)的類型而V用來表示值(VALUE)的類型。put和values是這么定義的:
  
  V put(K key, V value)Collection<V> values()
  
  NOTE:一個泛型不準(zhǔn)直接的或間接的是java.lang.Throwable的子類。因為異常是在運行時拋出的,所以它不可能預(yù)言什么類型的異常將在編譯時拋出.
  
  列表1的例子將比較List在JDK 1.4 和JDK1.5的不同
  
  package com.brainysoftware.jdk5.app16;import java.util.List;import java.util.ArrayList;public class GenericListTest { public static void main(String[] args) {  // in JDK 1.4  List stringList1 = new ArrayList();  stringList1.add("Java 1.0 - 5.0");  stringList1.add("without generics");  // cast to java.lang.String  String s1 = (String) stringList1.get(0);  System.out.println(s1.toUpperCase());  // now with generics in JDK 5  List<String> stringList2 = new ArrayList<String>();  stringList2.add("Java 5.0");  stringList2.add("with generics");  // no need for type casting  String s2 = stringList2.get(0);  System.out.PRintln(s2.toUpperCase()); }}
  
  在列表1中,stringList2是個泛型。聲明List<String>告訴編譯器List的實例能接受一個String對象。當(dāng)然,在另外的情況中,你能新建能接受各種對象的List實例。注重,當(dāng)從List實例中返回成員元素時,不需要對象轉(zhuǎn)化,因為他返回的了你想要的類型,也就是String.
  
  NOTE:泛型的類型檢查(type checking)是在編譯時完成的.
  
  最讓人感愛好的事情是,一個泛型是個類型并且能被當(dāng)作一個類型變量。比如,你想你的List儲存lists of Strings,你能通過把List<String>作為他的類型變量來聲明List。比如:
  
  List<List<String>> myListOfListsOfStrings;
  
  要從myList中的第一個List重新取得String,你可以這么用:
  
  String s = myListOfListsOfStrings.get(0).get(0);
  
  下一個列表中的ListOfListsTest類示范了一個List(命名為listOfLists)接受一個String List作為參數(shù)。
  
  package com.brainysoftware.jdk5.app16;import java.util.ArrayList;import java.util.List;public class ListOfListsTest { public static void main(String[] args) {  List<String> listOfStrings = new ArrayList<String>();  listOfStrings.add("Hello again");  List<List<String>> listOfLists = new ArrayList<List<String>>();  listOfLists.add(listOfStrings);  String s = listOfLists.get(0).get(0);  System.out.println(s); // prints "Hello again" }}
  
  另外,一個泛型接受一個或多個類型變量。比如,java.util.Map有兩個類型變量s。第一個定義了鍵(key)的類型,第二個定義了值(value)的類型。下面的例子講教我們?nèi)绾问褂脗€一個泛型Map.
  
  package com.brainysoftware.jdk5.app16;import java.util.HashMap;import java.util.Map;public class MapTest { public static void main(String[] args) {  Map<String, String> map = new HashMap<String, String>();  map.put("key1", "value1");  map.put("key2", "value2");  String value1 = map.get("key1"); }}
  
  在這個例子中,重新得到一個key1代表的String值,我們不需要任何類型轉(zhuǎn)換。
  
  沒有參數(shù)的情況下使用泛型
  
  既然在J2SE 5.0中收集類型已經(jīng)泛型化,那么,原來的使用這些類型的代碼將如何呢?很幸運,他們在JAVA 5中將繼續(xù)工作,因為你能使用沒有參數(shù)的泛型。比如,你能繼續(xù)像原來一樣使用List接口,正如下面的例子一樣。
  
  List stringList1 = new ArrayList();stringList1.add("Java 1.0 - 5.0");stringList1.add("without generics");String s1 = (String) stringList1.get(0);
  
  一個沒有任何參數(shù)的泛型被稱為原型(raw type)。它意味著這些為JDK1.4或更早的版本而寫的代碼將繼續(xù)在java 5中工作。
  
  盡管如此,一個需要注重的事情是,JDK5編譯器希望你使用帶參數(shù)的泛型。否則,編譯器將提示警告,因為他認(rèn)為你可能忘了定義類型變量s。比如,編譯上面的代碼的時候你會看到下面這些警告,因為第一個List被認(rèn)為是原型。
  
  Note: com/brainysoftware/jdk5/app16/GenericListTest.java
  uses unchecked or unsafe Operations.
  Note: Recompile with -Xlint:unchecked for details.
  
  當(dāng)你使用原型時,假如你不想看到這些警告,你有幾個選擇來達到目的:
  
  1.編譯時帶上參數(shù)-source 1.4
  
  2.使用@SupressWarnings("unchecked")注釋
  
  3.更新你的代碼,使用List<Object>. List<Object>的實例能接受任何類型的對象,就像是一個原型List。然而,編譯器不會報錯。
  
  使用 ? 通配符
  
  前

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 交口县| 滕州市| 加查县| 广丰县| 莱芜市| 阳西县| 鹤壁市| 大余县| 东辽县| 宜春市| 临沧市| 沅江市| 武平县| 深水埗区| 南涧| 蓝山县| 札达县| 韶山市| 金平| 和平区| 牙克石市| 镇雄县| 琼中| 郑州市| 甘孜县| 沙雅县| 镇巴县| 南宁市| 即墨市| 蕲春县| 河池市| 黑水县| 武平县| 兴海县| 石河子市| 南平市| 通城县| 阿克苏市| 诸城市| 固原市| 准格尔旗|