亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

輕松掌握 Java 泛型 (第 1 部分)

2019-11-18 13:15:13
字體:
來源:轉載
供稿:網友

  J2SE 1.5 - 代號為 Tiger - 計劃在 2003 年年底發布。我一直都熱衷于盡可能多地收集有關即將推出的新技術的預告信息,因此我將撰寫一系列的文章,討論可從 V1.5 中獲得的新的和經過重組的特性,本文是第一篇。我非凡想談談泛型類型并重點講述在 Tiger 中為了支持它們而進行的更改和調整。
  
  在許多方面,Tiger 肯定是迄今為止在 java 編程方面(包括對源語言語法的重大擴展)所取得的最大進步。Tiger 中計劃進行的最顯著的變化是添加泛型類型,正如在 JSR-14 原型編譯器中所預先展示的那樣(您可以立即免費下載該編譯器;請參閱參考資料)。
  
  讓我們從介紹泛型類型是什么以及添加了什么特性來支持它們開始吧。
  
  數據類型轉換和錯誤
  為理解泛型類型為何如此有用,我們要將注重力轉向 Java 語言中最輕易引發錯誤的因素之一 - 需要不斷地將表達式向下類型轉換(downcast)為比其靜態類型更為具體的數據類型(請參閱參考資料中的“The Double Descent bug pattern”,以了解進行數據類型轉換時,可能會碰到的麻煩的某些方面)。
  
  程序中的每個向下類型轉換對于 ClassCastException 而言都是潛在的危險,應當盡量避免它們。但是在 Java 語言中它們通常是無法避免的,即便在設計優良的程序中也是如此。
  
  在 Java 語言中進行向下類型轉換最常見的原因在于,經常以專用的方式來使用類,這限制了方法調用所返回的參數可能的運行時類型。例如,假定往 Hashtable 中添加元素并從中檢索元素。那么在給定的程序中,被用作鍵的元素類型和存儲在散列表中的值類型,將不能是任意對象。通常,所有的鍵都是某一特定類型的實例。同樣地,存儲的值將共同具有比 Object 更具體的公共類型。
  
  但是在目前現有的 Java 語言版本中,不可能將散列表的特定鍵和元素聲明為比 Object 更具體的類型。在散列表上執行插入和檢索操作的類型特征符告訴我們只能插入和刪除任意對象。例如,put 和 get 操作的說明如下所示:
  
  清單 1. 插入/檢索類型說明表明只能是任意對象
  
  class Hashtable {
   Object put(Object key, Object value) {...}
   Object get(Object key) {...}
   ...
  }
  
  因此,當我們從類 Hashtable 的實例檢索元素時,比如,即使我們知道在 Hashtable 中只放了 String,而類型系統也只知道所檢索的值是 Object 類型。在對檢索到的值進行任何特定于 String 的操作之前,必須將它強制轉換為 String,即使是將檢索到的元素添加到同一代碼塊中,也是如此!
  
  清單 2. 將檢索到的值強制轉換成 String
  
  import java.util.Hashtable;
  class Test {
   public static void main(String[] args) {
    Hashtable h = new Hashtable();
    h.put(new Integer(0), "value");
    String s = (String)h.get(new Integer(0));
    System.out.PRintln(s);
   }
  }
  
  請注重 main 方法主體部分的第三行中需要進行的數據類型轉換。因為 Java 類型系統相當薄弱,因此代碼會因象上面那樣的數據類型轉換而漏洞百出。這些數據類型轉換不僅使 Java 代碼變得更加拖沓冗長,而且它們還降低了靜態類型檢查的價值(因為每個數據類型轉換都是一個選擇忽略靜態類型檢查的偽指令)。我們該如何擴展該類型系統,從而不必回避它呢?
  
  用泛型類型來解決問題!
  要消除如上所述的數據類型轉換,有一種普遍的方法,就是用泛型類型來增大 Java 類型系統。可以將泛型類型看作是類型“函數”;它們通過類型變量進行參數化,這些類型變量可以根據上下文用各種類型參數進行實例化。
  
  例如,與簡單地定義類 Hashtable 不同,我們可以定義泛型類 Hashtable< Key, Value>,其中 Key 和 Value 是類型參數。除了類名后跟著尖括號括起來的一系列類型參數聲明之外,在 Tiger 中定義這樣的泛型類的語法和用于定義普通類的語法很相似。例如,可以按照如下所示的那樣定義自己的泛型 Hashtable 類:
  
  清單 3. 定義泛型 Hashtable 類
  
  class Hashtable< Key, Value> { ... }
  
  然后可以引用這些類型參數,就像我們在類定義主體內引用普通類型那樣,如下所示:
  
  清單 4. 像引用普通類型那樣引用類型參數 class Hashtable< Key, Value> {
   ...
   Value put(Key k, Value v) {...}
   Value get(Key k) {...}
  }
  
  類型參數的作用域就是相應類定義的主體部分(除了靜態成員之外)(在下一篇文章中,我們將討論為何 Tiger 實現中有這樣的“怪習”,即必須對靜態成員進行此項限制。請留意?。?。
  
  創建一個新的 Hashtable 實例時,必須傳遞類型參數以指定 Key 和 Value 的類型。傳遞類型參數的方式取決于我們打算如何使用 Hashtable。在上面的示例中,我們真正想要做的是創建 Hashtable 實例,它只將 Integer 映射為 String??梢杂眯碌?Hashtable 類來完成這件事:
  
  清單 5. 創建將 Integer 映射為 String 的實例
  
  import java.util.Hashtable;
  class Test {
   public static void main(String[] args) {
    Hashtable< Integer, String> h = new Hashtable< Integer, String>();
    h.put(new Integer(0), "value");
    ...
   }
  }
  
  現在不再需要數據類型轉換了。請注重用來實例化泛型類 Hashtable 的語法。就像泛型類的類型參數用尖括號括起來那樣,泛型類型應用程序的參數也是用尖括號括起來的。
  
  清單 6. 除去不必要的數據類型轉換
  
  ...
  String s = h.get("key");
  System.out.println(s);
  
  當然,程序員若只是為了能使用泛型類型而必須重新定義所有的標準實用程序類(比如 Hashtable 和 List)的話,則可能會是一項浩大的工程。幸好,Tiger 為用戶提供了所有 Java 集合類的泛型版本,因此我們不必自己動手來重新定義它們了。此外,這些類能與舊代碼和新的泛型代碼一起無縫工作(下個月,我們會說明如何做到這一點)。
  
  Tiger 的基本類型限制
  Tiger 中類型變量的限制之一就是,它們必須用引用類型進行實例化 - 基本類型不起作用。因此,在上面這個示例中,無法完成創建從 int 映射到 String 的 Hashtable。
  
  這很遺憾,因為這意味著只要您想把基本類型用作泛型類型的參數,您就必須把它們組裝為對象。另一方面,當前的這種情況是最糟的;您不能將 int 作為鍵傳遞給 Hashtable,因為所有的鍵都必須是 Object 類型。
  
  我們真正想看到的是,基本類型可以自動進行包裝(boxing)和解包裝(unboxing),類似于用 C# 所進行的操作(或者比后者更好)。遺憾的是,Tiger 不打算包括基本類型的自動包裝(但是人們可以一直期待 Java 1.6 中出現該功能!)。
  
  受限泛型
  有時我們想限制可能出現的泛型類的類型實例化。在上面這個示例中,類 Hashtable 的類型參數可以用我們想用的任何類型參數進行實例化,但是對于其它某些類,我們或許想將可能的類型參數集限定為給定類型范圍內的子類型。
  
  例如,我們可能想定義泛型 ScrollPane 類,它引用普通的帶有滾動條功能的 Pane。被包含的 Pane 的運行時類型通常會是類 Pane 的子類型,但是靜態類型就只是 Pane。
  
  有時我們想用 getter 檢索被包含的 Pane,但是希望 getter 的返回類型盡可能具體些。我們可能想將類型參數 MyPane 添加到 ScrollPane 中,該類型參數可以用 Pane 的任何子類進行實例化。然后可以用這種形式的子句:extends Bound 來說明 MyPane 的聲明,從而來設定 MyPane 的范圍:
  
  清單 7. 用 extends 子句來說明 MyPane 聲明
  
  class ScrollPane< MyPane extends Pane> { ... }
  
  當然,我們可以完全不使用顯式的范圍,只要能確保沒有用不適當的類型來實例化類型參數。
  
  為什么要自找麻煩在類型參數上設定范圍呢?這里有兩個原因。首先,范圍使我們增加了靜態類型檢查功能。有了靜態類型檢查,就能保證泛型類型的每次實例化都符合所設定的范圍。
  
  其次,因為我們知道類型參數的每次實例化都是這個范圍之內的子類,所以可以放心地調用類型參數實例出現在這個范圍之內的任何方法。假如沒有對參數設定顯式的范圍,那么缺省情況下范圍是 Object,這意味著我們不能調用范圍實例在 Object 中未曾出現的任何方法。
  
  多態方法
  除了用類型參數對類進行參數化之外,用類型參數對方法進行參數化往往也同樣很有用。泛型 Java 編程用語中,用類型進行參數化的方法被稱為多態方法(Polymorphic method)。
  
  多態方法之所以有用,是因為有時候,在一些我們想執行的操作中,參數與返回值之間的類型相關性原本就是泛型的,但是這個泛型性質不依靠于任何類級的類型信息,而且對于各個方法調用都不相同。
  
  例如,假定想將 factory 方法添加到 List 類中。這個靜態方法只帶一個參數,也將是 List 唯一的元素(直到添加了其它元素)。因為我們希望 List 成為其所包含的元素類型的泛型,所以希望靜態 factory 方法帶有類型變量 T 這一參數并返回 List< T> 的實例。
  
  但是我們確實希望該類型變量 T 能在方法級別上進行聲明,因為它會隨每次單獨的方法調用而發生改變(而且,正如我在下一篇文章中將討論的那樣,Tiger 設計的“怪習”規定靜態成員不在類級類型參數的范疇之內)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
免费不卡欧美自拍视频| 日本一区二区三区在线播放| 欧美高清视频一区二区| 亚洲午夜国产成人av电影男同| 黑人巨大精品欧美一区免费视频| 欧美日韩一区二区精品| 国产欧美一区二区三区在线| 久久久久久国产精品三级玉女聊斋| 欧美激情精品久久久久久| 久久视频在线观看免费| 亚洲精品ady| 91中文精品字幕在线视频| 久久久久久国产| 欧美大片大片在线播放| 亚洲xxxxx| 国产美女直播视频一区| 深夜福利91大全| 欧美成人免费在线视频| 成人高h视频在线| 97精品一区二区视频在线观看| 日韩小视频在线| 91在线免费视频| 欧美激情亚洲综合一区| 7777kkkk成人观看| 欧美成人精品在线观看| 精品福利在线看| 亚洲精品不卡在线| 中文字幕av一区二区| 91久久久在线| 97久久国产精品| 欧美亚洲视频在线看网址| 亚洲另类欧美自拍| 国产欧美韩国高清| 91av视频在线免费观看| 欧美电影在线观看高清| 国产精品一区二区三区久久| 亚洲电影成人av99爱色| 日韩国产高清视频在线| 最近2019免费中文字幕视频三| 5566日本婷婷色中文字幕97| 社区色欧美激情 | 亚洲欧美中文字幕在线一区| 亚洲一区二区三区视频| 日韩精品亚洲元码| 亚洲精品第一页| 日韩av网站导航| 在线国产精品视频| 中文字幕日韩av| zzijzzij亚洲日本成熟少妇| 亚洲精品成人久久电影| 色偷偷av亚洲男人的天堂| 国产视频久久网| 亚洲激情电影中文字幕| 中文字幕日韩综合av| 午夜精品蜜臀一区二区三区免费| 欧美与黑人午夜性猛交久久久| 色噜噜久久综合伊人一本| 一区二区亚洲欧洲国产日韩| 国产婷婷成人久久av免费高清| 中文字幕在线观看亚洲| 欧美日韩在线第一页| 38少妇精品导航| 国产精品黄色av| 久久免费精品视频| 日本精品视频在线播放| 成人久久久久久久| 日韩中文字幕免费视频| 国内精品久久影院| 日韩电影第一页| 欧美国产日本高清在线| 欧美国产日韩在线| 精品久久久久久久久久久| 日本午夜在线亚洲.国产| 亚洲wwwav| 在线性视频日韩欧美| 欧洲成人免费视频| 久久久久久久激情视频| 亚洲第一福利在线观看| 国产精品自产拍在线观看| 国产精品久久久久久久久久| 国产精品福利在线观看网址| 国产一区二区三区在线视频| 欧美午夜性色大片在线观看| 亚洲男人天堂古典| 久久久精品免费视频| 久久九九有精品国产23| 亚洲午夜精品视频| 日本高清视频一区| …久久精品99久久香蕉国产| 亚洲开心激情网| 欧美巨乳美女视频| 色偷偷偷亚洲综合网另类| 亚洲欧美综合另类中字| 久久国产精品免费视频| 亚洲精品一区av在线播放| 欧美精品一二区| 国产亚洲精品91在线| 国产亚洲欧洲高清一区| 色偷偷av亚洲男人的天堂| 91免费高清视频| 亚洲成成品网站| 美女啪啪无遮挡免费久久网站| 亚洲人成在线播放| 国产成+人+综合+亚洲欧美丁香花| 亚洲free性xxxx护士白浆| 免费av在线一区| 国产国语刺激对白av不卡| 日韩大片在线观看视频| 亚洲福利视频久久| 成人欧美一区二区三区在线湿哒哒| 国产欧美日韩视频| 亚洲欧美在线看| 亚洲色图17p| 久久资源免费视频| 国产一区二区三区精品久久久| 色爱av美腿丝袜综合粉嫩av| 亚洲美女自拍视频| 亚洲精品国产欧美| 欧美精品精品精品精品免费| 日本精品一区二区三区在线播放视频| 国产亚洲人成a一在线v站| 欧美激情一级欧美精品| 欧美精品午夜视频| 一区二区三区美女xx视频| 亚洲男人天堂手机在线| 欧美精品成人在线| 日韩精品有码在线观看| 亚洲欧洲日产国码av系列天堂| 久久九九国产精品怡红院| 亚洲国产欧美在线成人app| 亚洲国模精品一区| 欧美日韩精品在线观看| 亚洲精品ady| 欧美日韩国产精品一区二区不卡中文| 日韩av电影手机在线| 欧美精品videos另类日本| 欧美一级片在线播放| 欧美午夜片欧美片在线观看| 青青草精品毛片| 日韩免费av一区二区| 日韩精品极品在线观看播放免费视频| 欧美xxxx综合视频| 这里只有精品视频在线| 国产人妖伪娘一区91| 欧美与黑人午夜性猛交久久久| 成人国产精品av| 一个色综合导航| 狠狠色香婷婷久久亚洲精品| 欧美黄网免费在线观看| 日韩欧美国产免费播放| 欧美精品九九久久| 最近2019中文字幕在线高清| 日韩在线观看免费全集电视剧网站| 日韩美女在线观看| 欧美综合在线观看| 日韩精品免费在线视频| 亚洲国产精品热久久| 日韩电影在线观看免费| 日韩在线精品视频| 亚洲а∨天堂久久精品9966| 国产成人综合亚洲| 欧美日韩国产麻豆| 欧美亚洲视频一区二区| 在线看日韩av|