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

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

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

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

  有效的構造函數調用
  首先,為了對類型參數構造合法的 new 表達式(如 new T()),必須確保我們調用的構造函數對于 T 的每個實例化都有效。但由于我們只知道 T 是其已聲明界限的子類型,所以我們不知道 T 的某一實例化將有什么構造函數。要解決這一問題,可以用下述三種方法之一:
  
  要求類型參數的所有實例化都包括不帶參數的(zeroary)構造函數。
  只要泛型類的運行時實例化沒有包括所需的構造函數,就拋出異常。
  修改語言的語法以包括更詳盡的類型參數界限。
  
  第 1 種方法:需要不帶參數的構造函數
  只要求類型參數的所有實例化都包括不帶參數的構造函數。該解決方案的優點是非常簡單。使用這種方法也有先例。
  
  處理類似問題的現有 java 技術(象 JavaBean 技術)就是通過要求一個不帶參數的構造函數來解決問題的。然而,該方法的一個主要缺點是:對于許多類,沒有合理的不帶參數的構造函數。
  
  例如,表示非空容器的任何類在構造函數中必然使用表示其元素的參數。包括不帶參數的構造函數將迫使我們先創建實例,然后再進行本來可以在構造函數調用中完成的初始化。但該實踐會導致問題的產生(您可能想要閱讀 2002 年 4 月發表的本專欄文章“The Run-on Initializer bug pattern”,以獲取具體信息;請參閱參考資料。)
  
  第 2 種方法:當缺少所需構造函數時,拋出異常
  處理該問題的另一種方法是:只要泛型類的運行時實例化沒有包括所需構造函數,就拋出異常。請注重:必須在運行時拋出異常。因為 Java 語言的遞增式編譯模型,所以我們無法靜態地確定所有將在運行時發生的泛型類的實例化。例如,假設我們有如下一組泛型類:
  
  清單 1.“裸”類型參數的 New 操作
  
  class C< T> {
   T makeT() {
    return new T();
   }
  }
  
  class D< S> {
   C< S> makeC() {
    return new C< S>();
   }
  }
  
  現在,在類 D< S> 中,構造了類 C< S> 的實例。然后,在類 C 的主體中,將調用 S 的不帶參數的構造函數。這種不帶參數的構造函數存在嗎?答案當然取決于 S 的實例化!
  
  比方說,假如 S 被實例化為 String,那么答案是“存在”。假如它被實例化為 Integer,那么答案是“不存在”。但是,當編譯類 D 和 C 時,我們不知道其它類會構造什么樣的 D< S> 實例化。即使我們有可用于分析的整個程序(我們幾乎從來沒有這樣的 Java 程序),我們還是必須進行代價相當高的流分析來確定潛在的構造函數問題可能會出現在哪里。
  
  此外,這一技術所產生的錯誤種類對于程序員來說很難診斷和修復。例如,假設程序員只熟悉類 D 的頭。他知道 D 的類型參數的界限是缺省界限(Object)。假如得到那樣的信息,他沒有理由相信滿足聲明類型界限(如 D< Integer>)的 D 的實例化將會導致錯誤。事實上,它在相當長的時間里都不會引起錯誤,直到最后有人調用方法 makeC 以及(最終)對 C 的實例化調用方法 makeT。然后,我們將得到一個報告的錯誤,但這將在實際問題發生很久以后 — 類 D 的糟糕實例化。
  
  還有,對所報告錯誤的堆棧跟蹤甚至可能不包括任何對這個糟糕的 D 實例的方法調用!現在,讓我們假設程序員無權訪問類 C 的源代碼。他對問題是什么或如何修正代碼將毫無頭緒,除非他設法聯系類 C 的維護者并獲得線索。
  
  第 3 種方法:修改語法以獲得更詳盡的界限
  另一種可能性是修改語言語法以包括更詳盡的類型參數界限。這些界限可以指定一組可用的構造函數,它們必須出現在參數的每一個實例化中。因而,在泛型類定義內部,唯一可調用的構造函數是那些在界限中聲明的構造函數。
  
  同樣,實例化泛型類的客戶機類必須使用滿足對構造函數存在所聲明的約束的類來這樣做。參數聲明將充當類與其客戶機之間的契約,這樣我們可以靜態地檢查這兩者是否遵守契約。
  
  與另外兩種方法相比,該方法有許多優點,它答應我們保持第二種方法的可表達性以及與第一種方法中相同的靜態檢查程度。但它也有需要克服的問題。
  
  首先,類型參數聲明很輕易變得冗長。我們或許需要某種形式的語法上的甜頭,使這些擴充的參數聲明還過得去。另外,假如在 Tiger 以后的版本中添加擴充的參數聲明,那么我們必須確保這些擴充的聲明將與現有的已編譯泛型類兼容。
  
  假如將對泛型類型的與類型相關的操作的支持添加到 Java 編程中,那么它采用何種形式還不清楚。但是,從哪種方法將使 Java 代碼盡可能地保持健壯(以及使在它遭到破壞時盡可能輕易地修正)的觀點看,第三個選項無疑是最適合的。
  
  然而,new 表達式有另一個更嚴重的問題。
  
  多態遞歸
  更嚴重的問題是類定義中可能存在多態遞歸。當泛型類在其自己的主體中實例化其本身時,發生多態遞歸。例如,考慮下面的錯誤示例:
  
  清單 2. 自引用的泛型類
  
  class C< T> {
   public Object nest(int n) {
    if (n == 0) return this;
    else return new C< C< T>>().nest(n - 1);
   }
  }
  
  假設客戶機類創建新的 C< Object> 實例,并調用(比方說)nest(1000)。然后,在執行方法 nest() 的過程中,將構造新的實例化 C< C< Object>>,并且對它調用 nest(999)。然后,將構造實例化 C< C< C< Object>>>,以此類推,直到構造 1000 個獨立的類 C 的實例化。當然,我隨便選擇數字 1000;通常,我們無法知道在運行時哪些整數將被傳遞到方法 nest。事實上,可以將它們作為用戶輸入傳入。
  
  為什么這成為問題呢?因為假如我們通過為每個實例化構造獨立類來支持泛型類型的與類型相關的操作,那么,在程序運行以前,我們無法知道我們需要構造哪些類。但是,假如類裝入器為它所裝入的每個類查找現有類文件,那么它會如何工作呢?
  
  同樣,這里有幾種可能的解決辦法:
  
  對程序可以產生的泛型類的實例化數目設置上限。
  靜態禁止多態遞歸。
  在程序運行時隨需構造新的實例化類。
  
  第 1 種:對實例化數設置上限
  我們對程序可以產生的泛型類的實例化數目設置上限。然后,在編譯期間,我們可以對一組合法的實例化確定有限界限,并且僅為該界限中的所有實例化生成類文件。
  
  該方法類似于在 C++ 標準模板庫中完成的事情(這使我們有理由擔心它不是一個好方法)。該方法的問題是,和為錯誤的構造函數調用報告錯誤一樣,程序員將無法預知其程序的某一次運行將崩潰。例如,假設實例化數的界限為 42,并且使用用戶提供的參數調用先前提到的 nest() 方法。那么,只要用戶輸入小于 42 的數,一切都正常。當用戶輸入 43 時,這一計劃不周的設計就會失敗?,F在,設想一下可憐的代碼維護者,他所面對的任務是重新組合代碼并試圖弄清楚幻數 42 有什么非凡之處。
  
  第 2 種:靜態禁止多態遞歸
  為什么我們不向編譯器發出類似“靜態禁止多態遞歸”這樣的命令呢?(唉!要是那么簡單就好了。)當然,包括我在內的許多程序員都會反對這種策略,它抑制了許多重要設計模式的使用。
  
  例如,在泛型類 List< T> 中,您真的想要防止 List< List< T>> 的構造嗎?從方法返回這種列表對于構建許多很常用的數據結構很有用。事實證實我們無法防止多態遞歸,即使我們想要那樣,也是如此。就象靜態檢測糟糕的泛型構造函數調用一樣,禁止多態遞歸會與遞增式類編譯發生沖突。我們先前的簡單示例(其中,多態遞歸作為一個簡單直接的自引用發生)會使這一事實變得模糊。但是,自引用對于在不同時間編譯的大多數類經常采用任意的間接級別。再提一次,那是因為一個泛型類可以用其自己的類型參數來實例化另一個泛型類。
  
  下面的示例涉及兩個類之間的多態遞歸:
  
  清單 3. 相互遞歸的多態遞歸
  
  class C< T> {
   public Object potentialNest(int n) {
    if (n == 0) return this;
    else return new D< T>().nest(n - 1);
   }
  }
  
  class D< S> {
   public Object nest(int n) {
    return new C< C< S>>().nest(n);
   }
  }
  
  在類 C 或 D 中顯然沒有多態遞歸,但象 new D< C< Object>>().nest(1000) 之類的表達式將引起類 C 的 1000 次實例化。
  
  或許,我們可以將新屬性添加到類文件中,以表明類中所有不同泛型類型實例化,然后在編譯其它類時分析這些實例化,以進行遞歸。但是,我們還是必須向程序員提供希奇的和不直觀的錯誤消息。
  
  在上面的代碼中,我們在哪里報告錯誤呢?在類 D 的編譯過程中還是在包含不相干表達式 new D< C< Object>>().nest(1000) 的客戶機類的編譯過程中呢?無論是哪一種,除非程序員有權訪問類 C 的源代碼,否則他無法預知何時會發生編譯錯誤。
  
  第 3 種:實時構造新的實例化類
  另一種方法是在程序運行時按需構造新的實例化類。起先,這種方法似乎與 Java 運行時完全不兼容。但實際上,實現該策略所需的全部就是使用一個修改的類裝入器,它根據“模板(template)”類文件構造新的實例化類。
  
  JVM 規范已經答應程序員使用修改的類裝入器;事實上,許多流行的 Java 應用程序(如 Ant、JUnit 和 DrJava)都使用它們。該方法的缺點是:修改的類裝入器必須與其應用程序一起分布,以在較舊的 JVM 上運行。因為類裝入器往往比較小,所以這個開銷不會大。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美精品一区二区三区国产精品| 国产精品久久久久77777| 久久久www成人免费精品| 97精品一区二区视频在线观看| 日韩成人av一区| 欧美高清在线播放| 国语自产精品视频在免费| 亚洲三级黄色在线观看| 欧美自拍视频在线观看| 韩国精品久久久999| 亚洲男人天堂2024| 亚洲视频自拍偷拍| 欧美丰满片xxx777| 国产一区红桃视频| 日本不卡视频在线播放| 国产精品99久久久久久久久| 久久久女人电视剧免费播放下载| 国产精品老女人视频| 国产精品96久久久久久又黄又硬| 国产ts人妖一区二区三区| 欧美大胆a视频| 77777亚洲午夜久久多人| 欧美激情欧美狂野欧美精品| 国产成人av在线播放| 日韩在线免费观看视频| 日韩美女在线播放| 午夜精品福利在线观看| 亚洲人免费视频| 亚洲精品国产精品乱码不99按摩| 久久免费视频网站| 欧美有码在线观看视频| 在线观看久久久久久| 亚洲韩国欧洲国产日产av| 国产精品av电影| 亚洲国产一区二区三区在线观看| 国产成人精品免高潮费视频| 18一19gay欧美视频网站| 国产伊人精品在线| 欧美精品18videos性欧美| 国产乱人伦真实精品视频| 国产999精品视频| 欧美黑人性生活视频| 在线成人激情黄色| 精品久久久一区二区| 国产精品国产三级国产专播精品人| 日本精品一区二区三区在线| 欧美精品videofree1080p| 久久久久久久久久久人体| 亚洲精品美女免费| 日韩av影院在线观看| 日韩av中文字幕在线免费观看| 国产成人精品亚洲精品| 日本中文字幕成人| 午夜精品一区二区三区在线播放| 青青a在线精品免费观看| 欧美第一淫aaasss性| 亚洲人成亚洲人成在线观看| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲qvod图片区电影| 美女av一区二区| 欧美在线精品免播放器视频| 久久久999成人| 福利精品视频在线| 久久久久久av| 亚洲精品美女视频| 欧美理论电影在线播放| 久久久久久久色| 亚洲iv一区二区三区| 日韩激情第一页| 亚洲女同精品视频| 国产深夜精品福利| www高清在线视频日韩欧美| 久久久久久久久综合| 国产精品自产拍在线观看| 欧美一级大片视频| 欧美性xxxx极品高清hd直播| 日本一欧美一欧美一亚洲视频| 国产精品91免费在线| 色狠狠久久aa北条麻妃| 中文字幕精品视频| 久久精品成人欧美大片古装| 国产精品自产拍在线观看| 亚洲欧美日韩图片| 欧美日韩国产在线| 亚洲视频在线观看网站| 国产精品日日摸夜夜添夜夜av| 九九热这里只有精品免费看| 亚洲国产精品嫩草影院久久| 国产视频一区在线| 国产精品久久久久久久av大片| 欧美激情在线狂野欧美精品| 久久网福利资源网站| 中文字幕精品久久| 亚洲男人7777| 国产精品久久久久久久午夜| 欧美在线亚洲一区| 欧美性受xxxx黑人猛交| 永久免费毛片在线播放不卡| 久久精品国产亚洲一区二区| 亚洲精品国产精品国产自| 国产精品第2页| 日韩在线一区二区三区免费视频| 欧美视频在线看| 在线看欧美日韩| 97视频免费看| 久久精品电影网站| 91在线观看免费高清| 亚洲欧美一区二区激情| 成人黄色av免费在线观看| 亚洲影视九九影院在线观看| 国产精品电影一区| 欧美午夜www高清视频| 亚洲成年人影院在线| 欧美精品久久久久久久免费观看| 2019最新中文字幕| www.国产精品一二区| 亚洲丝袜av一区| 精品亚洲va在线va天堂资源站| 国产97在线|亚洲| 热re91久久精品国99热蜜臀| 亚洲一区二区三区视频播放| 欧美精品制服第一页| 欧美成人激情视频免费观看| 精品久久香蕉国产线看观看gif| 福利一区福利二区微拍刺激| 91视频国产精品| 7m精品福利视频导航| 欧美一级淫片videoshd| 日本精品一区二区三区在线播放视频| 亚洲福利视频在线| 欧美性猛交xxxx富婆弯腰| 日韩欧美主播在线| 亚洲精品不卡在线| 亚洲精品美女在线观看播放| 久久精品中文字幕一区| 成人动漫网站在线观看| 精品性高朝久久久久久久| 欧美天天综合色影久久精品| 红桃视频成人在线观看| 中文字幕在线看视频国产欧美| 一区二区三区美女xx视频| 成人精品在线视频| 成人h视频在线观看播放| 懂色av影视一区二区三区| 国产精品麻豆va在线播放| 日韩欧美在线视频| 国产精品国内视频| 91av在线看| 欧美国产日产韩国视频| 国内精品免费午夜毛片| 欧美激情亚洲另类| 国产精品白丝av嫩草影院| 色偷偷9999www| 亚洲图片欧洲图片av| 欧美精品生活片| 国产精品久久久久久久久久久久久| 欧美成人在线免费| 亚洲女成人图区| 亚洲伦理中文字幕| 日本精品免费一区二区三区| 777午夜精品福利在线观看| 国产盗摄xxxx视频xxx69| 欧美日韩一区二区精品| 78m国产成人精品视频|