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

Effective Java 實戰:拒絕原生態類型,擁抱泛型與通配符

     編輯:Java 綜合教學

為什麼不應在新代碼中使用原生態類型?

在 Java 開發中,原生態類型指的是未帶類型參數的泛型類或介面(如 List 而非 List<String>)。雖然為了向後兼容 Java 允許使用原生態類型,但這會嚴重削弱類型安全,導致運行時才拋出 ClassCastException,而非編譯期捕獲錯誤。

一個血淚教訓的例子

public class RawTypeDemo {
    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        unsafeAdd(strings, Integer.valueOf(42)); // 編譯器只會警告
        String s = strings.get(0); // 運行時拋出 ClassCastException
    }

    private static void unsafeAdd(List list, Object o) {
        list.add(o);
    }
}

若將參數改為 List<Object>,IDE 會直接報錯,因為 List<String> 不是 List<Object> 的子類型。這正是泛型的不變性所帶來的保護。

無限制通配符類型:安全的替代方案

當不關心集合元素的具體類型時,應使用 Set<?> 而非原生態 Set。兩者的關鍵區別在於:

  • 原生態類型:可向其中插入任意對象,輕易破壞類型約束。
  • 通配符類型:除 null 外,不可插入任何元素,編譯器保證類型安全。
// 推薦寫法:使用無限制通配符
static int numElementsInCommon(Set<?> s1, Set<?> s2) {
    int result = 0;
    for (Object o : s1) {
        if (s2.contains(o)) result++;
    }
    return result;
}

兩個特例:必須使用原生態類型的場景

  1. 類字面量:規範不允許參數化類型,只能用 List.class、String[].class,不能用 List<String>.class。
  2. instanceof 檢查:因泛型資訊運行時擦除,if (obj instanceof Set<String>) 非法。正確做法是:
    if (obj instanceof Set) {
        Set<?> s = (Set<?>) obj; // 必須轉為通配符類型,而非原生態
    }

總結

原生態類型是為了兼容舊代碼而存在的「妥協產物」。在新代碼中,請堅持使用參數化類型或無限制通配符,讓編譯器為你把關,將潛在的運行時錯誤提前到編譯期發現。

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