麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

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

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

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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美成人国产va精品日本一级 | 亚洲一级网站 | 久久亚洲国产午夜精品理论片 | 神马视频我不卡 | 国内精品久久久久久久星辰影视 | 羞羞视频免费视频欧美 | 国产精品久久久久久久久久久久午夜 | 黄色高清av| 国产乱淫av | hd性videos意大利复古 | 成年免费观看视频 | 欧美日韩在线视频一区 | 精品国产乱码一区二区三区四区 | 久久国产精品小视频 | 亚洲午夜久久久久 | 亚洲成人福利在线观看 | 成人性视频在线 | 91羞羞| 久久影库| 国产精品久久久久无码av | 女人叉开腿让男人桶 | 日本在线观看中文字幕 | 国产又粗又爽又深的免费视频 | 精品久久久久久久 | 久久精品1区2区 | 久久精品一级片 | 特级a欧美做爰片毛片 | 性生活香蕉视频 | 密室逃脱第一季免费观看完整在线 | 少妇的肉体的满足毛片 | 国产交换3p国产精品 | 成人爽a毛片免费啪啪红桃视频 | 日本中文字幕网址 | 成年人观看免费视频 | 国产二区三区在线播放 | 成人国产高清 | 欧美一级做 | 亚洲性视频 | 欧美a级大胆视频 | 成人在线视频网 | 欧美在线观看黄色 |