在用 Java 編程時,我遇到了以下問題。
使用建構式時:以下代碼作業正常。
public class Generics<T> {
private T data;
public static <T> Generics<T> of(T data) {
return new Generics<>(data);
}
public Generics(T data) {
this.data = data;
}
}
當使用構建器時:發生錯誤,說提供的物件型別如下。

我使用了 Project Lombok 提供的構建器。
為什么上面代碼中的構建器泛型不起作用?
uj5u.com熱心網友回復:
顯然 Lombok 生成了一個靜態泛型builder()方法。您可以<T>在方法名稱之前使用指定泛型靜態方法的泛型型別,如下所示:
return Generics.<T>builder()
.data(data)
.build();
如果您在呼叫 時未指定泛型型別builder(),則會得到原始型別,此時泛型型別推斷不再有效。
uj5u.com熱心網友回復:
您需要明確添加泛型:return Generics.<T>builder()- 添加它<T>,一切都會好起來的。
解釋
Java 是主動型別化的:每個運算式以及運算式的幾乎每個部分都有一個實際型別;java 不允許事情一直處于不確定狀態,直到以后;沒有“中間件 - 呃,我們會看到它去哪里”這樣的東西。
這意味著Generics.builder(),作為運算式,需要由系統輸入。構建器類需要<T>相同的(它是一個Generics.GenericsBuilder<X>- 其中Builder是泛型的靜態內部類,并被定義為public static class GenericsBuilder<X>.
Java 不能簡單地得出您希望 X 和 T 為同一型別的結論。
展望未來,它可以確定 X 應該“自動”為 T,無需您參與:它可以檢查.data(data)呼叫,因為該data方法在構建器中定義為:
public GenericsBuilder<X> data(X data)
因此,無論型別data(變數)might be (it'sT here, given that it's the parameter defined asT 資料`),因此,java 可以得出結論,X 應該是 T。
否則,java 可以看得更遠, to build(),并注意到 this 回傳X,并且由回傳型別定義為 的方法回傳T,因此也給 java 機會說:啊,X == T,對。
但這不是 java 的作業方式。很大程度上是因為.data當決議器繼續執行時,當X您剛剛創建的構建器(X宣告中的public static <X> Generics.GenericsBuilder<X> builder())必須處于某種未知的不確定狀態一段時間時,即使弄清楚該方法可能意味著什么也相當困難。試圖弄清楚其余的意味著什么。鑒于 java 允許方法多載(2 個不同的方法具有相同的名稱和相同數量的引數,但引數型別不同,可能包含要啟動的泛型) - 這將是一個組合爆炸,意味著您可以撰寫需要字面上決議數年。
因此,java 不能那樣作業,它必須確定X應該完全來自運算式的內容Generics.builder(),而它顯然不能。
解決方案是使用這種有點奇特的語法直接撰寫它:Generics.<T>builder().
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/363403.html
