Java泛型數組為何仍會導致類型錯誤?

Java泛型數組的類型安全陷阱:深入剖析運行時錯誤

本文探討Java泛型中一個易混淆的問題:即使經過類型轉換,泛型數組仍可能導致運行時類型錯誤。我們將通過代碼示例分析其根本原因。

下圖展示了問題所在:

Java泛型數組為何仍會導致類型錯誤?

以下代碼片段定義了一個名為Pair的泛型類,并通過main方法演示潛在的類型錯誤:

private static class Pair<T> {     public T t;      public Pair(T t) {         this.t = t;     } }  public static void main(String[] args) {     Pair<String>[] pairs = new Pair[10]; // 聲明一個Pair<String>數組      Object[] objPairs = pairs; // 將泛型數組賦值給Object數組      // 以下語句會拋出ArrayStoreException異常,因為實際數組類型為Pair<String>[]     // objPairs[0] = "123";      // 以下語句不會報錯,因為編譯器在運行時將Pair<String>視為Pair<Object>     objPairs[0] = new Pair<>(1);      // 以下語句會拋出ClassCastException異常,因為pairs[0]實際存儲的是Pair<Integer>     Pair<String> pair = pairs[0];  }

關鍵在于Pair[] pairs = new Pair[10];以及隨后將pairs數組賦值給Object類型的數組objPairs。 雖然表面上合法,但由于Java的類型擦除機制,編譯器在運行時將Pair視為Pair。 因此,objPairs[0] = new Pair(1);不會報錯。然而,嘗試將pairs[0]強制轉換為Pair時,由于實際存儲的是Pair,就會拋出ClassCastException異常。

立即學習Java免費學習筆記(深入)”;

這就是“仍會導致類型錯誤”的運行時錯誤的根源。盡管編譯器在編譯階段無法檢測到此錯誤,但數組的運行時類型仍然是Pair[],而不是Pair[]。試圖向其中放入不兼容的類型,將在運行時引發異常。 這正是Java泛型數組的局限性所在,正如書中8.6.3小節所總結的:不能創建參數化類型的數組。 類型擦除導致在編譯時無法完全保證類型安全,運行時檢查成為必要的補充。

? 版權聲明
THE END
喜歡就支持一下吧
點贊8 分享