首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

輕鬆掌握 Java 泛型(三):裸類型參數 new 操作的多態遞歸難題

     編輯:Java 相關知識

本系列探討 Java 泛型類型添加,本文聚焦未討論的限制之一:支援裸類型參數的 new 操作(如 new T())。Tiger/JSR-14 採用型別擦除實現泛型:僅用於型別檢查,隨即以界限替換。若 T 界限為 Object,new T() 擦除為 new Object(),顯非所望。若採用非擦除策略(每實例化一獨立類),new 操作引發更多基本語言設計決策。

有效建構子調用問題

為確保 new T() 合法,必須保證調用的建構子對 T 每個實例化有效。但僅知 T 為界限子型別,不知具體建構子。三種方案:

  1. 要求所有實例化含無參建構子(同前,缺點相同)。
  2. 運行時缺失拋異常(靜態無法知悉所有實例化,錯誤診斷極難,堆疊追蹤可能無關鍵資訊)。
  3. 擴充語法:類型參數界限宣告必須建構子集合(契約式,靜態檢查雙方遵守,表達力與安全性最佳,雖語法較繁)。

更嚴重問題:多態遞歸

當泛型類在主體中實例化自身時發生。例:

class C<T> {
  Object nest(int n) {
    if (n == 0) return this;
    else return new C<C<T>>().nest(n - 1);
  }
}

客戶端呼叫 new C<Object>().nest(1000) 將構造 1000 層巢狀實例化 C<C<...>>。若每實例化生成獨立類,編譯期無法知悉所需類集合(數值可能來自用戶輸入)。

三種應對策略

  1. 限制實例化數量上限(類 C++ STL,幻數導致不可預期崩潰,維護惡夢)。
  2. 靜態禁止多態遞歸(抑制重要設計模式如 List<List<T>>,且因增量編譯無法完全靜態檢測)。
  3. 運行時按需構造實例化類別:使用修改的類別載入器,依「模板類別檔」構建新實例化類(常量池留洞,載入時填充)。NextGen 編譯器即採此策略,原型基於 GJ 擴展,支援型別參數的轉型、instanceof、new,並用修改載入器解決多態遞歸。

結語

成熟執行期支援需解決許多微妙設計問題,處理不當將輕易抵消泛型優勢。期盼 Java 演進保持高表達力與健壯性。下一期將討論泛型類型最強大應用:Mixin。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved