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

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

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

2019-11-18 13:15:10
字體:
供稿:網(wǎng)友

  java 開發(fā)人員和研究人員 Eric Allen 討論了通過泛型類型添加對(duì) mixin 支持所帶來的影響,并以此文來結(jié)束他對(duì) JSR-14 和 Tiger 中泛型類型的由四部分組成的系列的討論。在相關(guān)論壇中與作者及其他讀者分享您對(duì)本文的看法。(您也可以單擊本文頂部或底部的“討論”來訪問該論壇。)至此,在這個(gè)討論 JSR-14 和 Tiger 中泛型類型的微型系列中,我們已經(jīng)探討了:
  
  泛型類型及被設(shè)計(jì)成支持它們的即將發(fā)布的功能
  
  基本類型、受約束的泛型以及多態(tài)方法上的限制
  
  幾個(gè)強(qiáng)加給這些 Java 擴(kuò)展的限制
  
  這些擴(kuò)展語言的編譯器所用的實(shí)現(xiàn)策略如何使這些限制成為必需
  
  在泛型類型中添加對(duì)“裸”類型參數(shù)的 new 操作的支持所帶來的影響
  
  本月,我們將探討在可以處理 mixin(可能被期望是泛型類型中最強(qiáng)大的功能)之前需要先解決的問題,以此來結(jié)束對(duì) Java 語言中泛型類型的討論。
  
  mixin vs 包裝
  mixin 是由其父類參數(shù)化的類。例如,請(qǐng)考慮以下這個(gè)泛型類,它繼續(xù)了它本身的類型參數(shù):
  
  class Scrollable< T> extends T {...}
  
  不要錯(cuò)過本系列的其它文章
  
  第 1 部分,輕松把握 Java 泛型(2003 年 2 月)
  
  第 2 部分,輕松把握 Java 泛型類型,第 2 部分(2003 年 3 月)
  
  第 3 部分,輕松把握 Java 泛型,第 3 部分(2003 年 4 月) 
  
  類 Scrollable 的目的是要向 GUI 窗口小部件嵌入添加可滾動(dòng)性所必需的功能性。這個(gè)泛型類的每個(gè)應(yīng)用都會(huì)繼續(xù)一個(gè)不同的父類。例如,Scrollable< JTextPane> 是 JTextPane 的子類,而 Scrollable< JEditorPane> 是 JEditorPane 的子類。對(duì)比這種嵌入功能的方法和 Java Swing 庫中現(xiàn)有的功能性,在這個(gè)庫中,假如我們想使 JComponent 是可滾動(dòng)的,必須將其“包裝”在 JScrollPane 中。
  
  包裝不僅需要添加訪問被包裝類的功能的轉(zhuǎn)發(fā)方法,而且它還阻止我們?cè)谛枰话b對(duì)象的實(shí)例的上下文中使用由此產(chǎn)生的可滾動(dòng)對(duì)象(例如,我們不能將 JScrollPane 傳遞到需要 JTextPane 的實(shí)例的方法中)。通過 Scrollable 的父類將其參數(shù)化,在繼續(xù)多個(gè)超類時(shí),我們就能保持對(duì)涉及滾動(dòng)的功能的單點(diǎn)控制。這樣能夠使用 mixin 讓我們重新獲得多重繼續(xù)性的某些強(qiáng)大功能,而又沒有附帶異常。
  
  在上面的示例中,我們甚至可以對(duì)類型參數(shù)施加約束以阻止它用于不適當(dāng)?shù)纳舷挛闹小@纾覀兛赡芟胧乖擃愋蛥?shù)強(qiáng)制為 JComponent 的子類:
  
  class Scrollable< T extends JComponent> extends T {...}
  
  那么我們的 mixin 只能繼續(xù) GUI 組件
  
  mixin 和泛型類:完美組合
  通常,mixin 作為獨(dú)立語言功能部件添加到某種語言中,就象 Jam 中的那樣。但是合并 mixin 以作為泛型類型系統(tǒng)的一部分很吸引人,幾乎可以說魅力無窮。原因是:mixin 和泛型類都能被認(rèn)為是將現(xiàn)有類映射到新類的函數(shù)。
  
  泛型類可被視為將它們的參數(shù)映射成新實(shí)例化的函數(shù)。mixin 可被視為將現(xiàn)有類映射成新子類的函數(shù)。通過使用泛型類型合并 mixin,我們能解決其它 mixin 公式的許多要害限制。
  
  在 Java 語言的 Jam 擴(kuò)展中,mixin 的超類類型沒有名稱;我們就不能在 mixin 主體中引用它。這一限制會(huì)迅速引起一連串各種其它問題。例如,在 Jam 中,禁止程序員將 this 作為參數(shù)傳遞給方法;無法對(duì)這樣的調(diào)用進(jìn)行類型檢查。這一限制的影響極大,因?yàn)樵S多最常見的設(shè)計(jì)模式都要依靠于能夠?qū)?this 作為參數(shù)傳遞。
  
  請(qǐng)考慮訪問者模式,其中用 for 方法為復(fù)合層次結(jié)構(gòu)中的每個(gè)類都定義了訪問者類。通常被訪問的類包含 accept 方法,它采用訪問者并傳遞 this 來調(diào)用該訪問者的方法。因此,在 Jam 中,訪問者模式不能和 mixin 一起使用。
  
  將 mixin 明確表述為泛型類,我們就始終有父類的句柄,它是該類繼續(xù)的類型參數(shù)。例如,我們可以將 Scrollable 的父類引用為類型 T。其結(jié)果是,在答應(yīng)將 this 作為類型參數(shù)傳遞時(shí)沒有任何根本性的困難。
  
  但是,將 mixin 明確表述為泛型類型時(shí)有其它一些明顯的困難。為了讓您初步體會(huì)可能產(chǎn)生的某些困難,我們將討論幾個(gè)突出的困難以及一些可能的解決方案。
  
  mixin 與類型消除
  在討論任何其它問題之前,我們應(yīng)該先指出,與上月討論的泛型類型的功能擴(kuò)展一樣,通過使用由 JSR-14 和 Tiger 使用的簡(jiǎn)單類型消除(type erasure)策略,不能將對(duì) mixin 的支持添加到 Java 語言中。
  
  要了解其原因,請(qǐng)考慮在繼續(xù)類型參數(shù)的類被消除時(shí)會(huì)出現(xiàn)什么情況。該類會(huì)最終繼續(xù)類型參數(shù)的界限!例如,上一個(gè)示例中類 Scrollable 的每個(gè)實(shí)例化最終都繼續(xù)類 JComponent。那顯然不是我們所希望的。
  
  為了通過泛型類型支持 mixin,我們需要獲得泛型類型實(shí)例化的運(yùn)行時(shí)表示。幸運(yùn)的是,編碼這一信息的方法有許多,它們實(shí)際上都向后與 Tiger 兼容。這樣的向后兼容編碼方案是泛型 Java(Generic Java)的 NextGen 公式的顯著特點(diǎn)(在參考資料一節(jié)中)。
  
  可用的超類構(gòu)造函數(shù)
  在我們希望答應(yīng)類繼續(xù)類型參數(shù)時(shí)立即出現(xiàn)的緊迫問題是要決定我們能調(diào)用什么樣的超級(jí)構(gòu)造函數(shù)?請(qǐng)回憶:每個(gè) Java 類構(gòu)造函數(shù)都必須調(diào)用超類的構(gòu)造函數(shù)。通常,通過查找超類并確保存在匹配的超級(jí)構(gòu)造函數(shù),類型檢查器確保這些超級(jí)構(gòu)造函數(shù)調(diào)用會(huì)成功。
  
  但是在我們對(duì)超類所知的一切只限于它是類型參數(shù)的實(shí)例化時(shí),對(duì)于什么樣的構(gòu)造函數(shù)可用于給定的實(shí)例化,我們沒有任何概念。而且請(qǐng)注重,類型檢查器甚至不能檢查是否每個(gè) mixin 實(shí)例化都會(huì)產(chǎn)生有效的超級(jí)構(gòu)造函數(shù)調(diào)用。其原因是:在某些其它上下文中,mixin 的參數(shù)可能用類型參數(shù)界限實(shí)例化了。
  
  例如,泛型類 jsplitPane< T> 可以創(chuàng)建 Scrollable< T> 的實(shí)例。除非我們知道將類型參數(shù) T 實(shí)例化為 JSplitPanes 的一切方法,否則我們不能知道在 Scrollable< T> 中調(diào)用的超級(jí)構(gòu)造函數(shù)是否有效。但是因?yàn)?Java 編碼答應(yīng)單獨(dú)的類編譯,所以在類型檢查期間,我們不能知道 jsplitPane 的所有實(shí)例。
  
  解決這一問題的各種方案與我們上月第 3 部分中討論的針對(duì)檢查 new 表達(dá)式的類型參數(shù)所提出的解決方案完全一致,因?yàn)槌?jí)構(gòu)造函數(shù)調(diào)用和 new 表達(dá)式都引用了給定類的同一個(gè)類構(gòu)造函數(shù)。讓我們回顧一下這些解決方案:
  
  需要一個(gè)不帶參數(shù)的(zeroary)構(gòu)造函數(shù),用于所有類型參數(shù)的實(shí)例化。
  當(dāng)沒有匹配的構(gòu)造函數(shù)時(shí),拋出運(yùn)行時(shí)異常。
  包含額外的類型參數(shù)注釋,告知我們這些實(shí)例化必須包含哪些構(gòu)造函數(shù)。
  就如 new 表達(dá)式的情況,前兩個(gè)解決方案有嚴(yán)重缺陷。通常在類定義中包含不帶參數(shù)的構(gòu)造函數(shù)沒有任何意義。而且,當(dāng)不存在任何匹配的構(gòu)造函數(shù)時(shí)就拋出異常也不太理想。究竟靜態(tài)類型檢查主要是嚴(yán)格防止那種異常。
  
  第三種解決方案可能有點(diǎn)繁瑣,但是它有許多優(yōu)點(diǎn)。注釋類型參數(shù),其中包括所有實(shí)例化都必須擁有的構(gòu)造函數(shù)集。這些注釋確切地告知我們針對(duì)類型參數(shù),我們可以可靠地調(diào)用什么樣的構(gòu)造函數(shù)。因此,當(dāng)類型參數(shù) T 用作泛型類的超類時(shí),T 的注釋確切地告知我們可以調(diào)用哪些超級(jí)構(gòu)造函數(shù)。假如 T 不包含注釋,那么類型檢查器會(huì)禁止它用作超類。
  
  意外的方法覆蓋
  任何 mixin 公式都會(huì)產(chǎn)生一個(gè)非常嚴(yán)重的問題:特定 mixin 的方法名可能與其超類的潛在實(shí)例化的方法名沖突。例如,假設(shè)類 Scrollable 包含不帶任何參數(shù)的方法 getSize 并返回一個(gè) Size 對(duì)象,編碼了其水平和垂直尺寸。現(xiàn)在,我們假設(shè)類 MyTextPane(JComponent 的子類)也包含不帶任何參數(shù)的方法 getSize,但返回一個(gè) int,表示調(diào)用它的對(duì)象的屏幕面積。
  
  產(chǎn)生的類顯示如下:
  
  清單 1. 意外方法覆蓋的示例
  
  class Scrollable< T extends JComponent> extends T {
   ...
   Size getSize() {...}
  }
  
  class MyTextPane extends JComponent {
   ...
   int getSize() {...}
  }
  
  new Scrollable< MyTextPane>()
  
  隨后 mixin 實(shí)例化 Scrollable< MyTextPane> 會(huì)包含兩個(gè)帶有同樣(空)參數(shù)類型的方法 getSize,但返回類型不一致!因?yàn)槲覀儾荒苤竿?Scrollable 的程序員或 MyTextPane 的程序員預(yù)見這個(gè)有問題的 getSize 覆蓋(究竟,他們甚至不可能在同一個(gè)開發(fā)團(tuán)隊(duì)),因此我們稱之為意外覆蓋。
  
  當(dāng) mixin 被明確表述為泛型類時(shí),意外覆蓋的問題非凡討厭。因?yàn)?mixin 的父類可能用類型參數(shù)被實(shí)例化,因此類型檢查器就不能確定意外方法覆蓋的所有情況。而且,在意外覆蓋出現(xiàn)時(shí)拋出運(yùn)行時(shí)異常是無法接受的,因?yàn)榭蛻魴C(jī)程序員無法猜測(cè)何時(shí)將拋出這樣的異常。假如我們想編寫可靠的程序,那么我們必須禁止在運(yùn)行時(shí)出現(xiàn)無法預(yù)料的錯(cuò)誤。
  
  另一個(gè)解決方案是只隱藏這些相互沖突的方法中的一個(gè),并解析所有匹配的方法調(diào)用以引用未隱藏的方法。這個(gè)解決方案的問題是我們希望諸如 Scrollable< MyTextPane> 這樣的 mixin 實(shí)例化可用于調(diào)用 Scrollable 對(duì)象的上下文以及調(diào)用 MyTextPane 對(duì)象的上下文中。隱藏 getSize 方法中的任一個(gè)都會(huì)在這兩個(gè)上下文中禁止使用 Scrollable< MyTextPane>。
  
  在 1998 年召開的有關(guān)編程語言原理的 ACM SIGPLAN-SIGACT 研討會(huì)(請(qǐng)參閱參考資料)上,F(xiàn)elleisen、Flatt 和 Krishnamurthi 提出了在 mixin 不屬于泛型類型的上下文中針對(duì)該問題的一個(gè)好的解決方案:基于使用 mixin 實(shí)例化的上下文來解決對(duì)相互沖突的方法的引用。在這個(gè)解決方案中,mixin 包含有

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 无为县| 赞皇县| 读书| 通化县| 香河县| 建宁县| 韶山市| 吉林省| 黄龙县| 曲麻莱县| 绥宁县| 哈密市| 武汉市| 利辛县| 丹凤县| 淅川县| 眉山市| 通辽市| 乌苏市| 天津市| 宜丰县| 香格里拉县| 剑河县| 吉木萨尔县| 诸暨市| 临海市| 札达县| 富源县| 新巴尔虎左旗| 日喀则市| 尼勒克县| 宁远县| 西林县| 疏附县| 石河子市| 德格县| 桐城市| 舟曲县| 兰溪市| 龙门县| 杂多县|