public class Holder {
private T value;
public Holder() {}
public Holder(T value) { this.value = value; }
public void setValue(T value) { this.value = value; }
}
// 客戶端代碼
Holder
錯誤訊息:
incompatible types: Holder<String> cannot be converted to Holder<Object>
Java 泛型預設為**不變**,即 `Holder
Holder
Holder
鑽石運算符**不會**根據目標型別 `Object` 反向推導建構式參數;它**只看實參**,推導出 `String`,再檢查相容性——失敗。
Holder holder = new Holder("xxx"); // 明確告知建構式用 Object
建構式接收 `Object`,實參 `"xxx"` 隱式上轉型為 `Object`,完全合法。
Holder holder = new Holder<>(); // 推導為 Holder(目標型別)
holder.setValue("xxx"); // String → Object 隱式上轉型
無參建構式無實參,編譯器**依賴目標型別** `Holder
Holder extends Object> holder = new Holder<>("xxx"); // 推導 Holder,符合上界
// holder.setValue("yyy"); // 編譯錯誤!通配符禁止寫入(除 null)
String s = holder.getValue(); // 唯讀安全
適用於**僅需讀取**元素的場景(如遍歷、序列化)。
| 寫法 | 編譯 | 運行型別 | 可寫入 | 適用場景 |
|---|---|---|---|---|
| `new Holder | ✅ | `Holder | 是 | 通用持有任意 Object |
| `new Holder<>(); setValue("xxx")` | ✅ | `Holder | 是 | 分步初始化 |
| `new Holder<>("xxx")` 直接賦值 | ❌ | — | — | 錯誤示範 |
| `Holder extends Object> h = new Holder<>("xxx")` | ✅ | `Holder | 否 | 唯讀、協變遍歷 |
「鑽石運算符會根據左邊型別推導右邊」
❌ **錯誤**。鑽石運算符**主要看實參**,輔助以目標型別(僅在無實參時)。上例有實參 `"xxx"`,故推導 `String`,與目標 `Object` 衝突。
「`Holder
` 繼承 `Holder `」
❌ **錯誤**。泛型類別之間**無繼承關係**,只有通配符建立的子型別關係:`Holder
Java 泛型的**不變性**導致 `Holder