在Collections.java類中存在以下方法:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
我想知道型別 T 是如何定義的!通常在方法引數中使用型別引數,我可以想象在編譯時,根據使用的引數替換T。例子:
public static final <T> List<T> returnList(List<T> list) {
return list;
}
...
List<String> list = ...;
Collections.returnList(list); // I know that it returns a List of string, since list is defined to contain String elements.
但是這里是如何推斷 T 的:
Collections.emptyList(); // It returns a list, but how T is inferred?
uj5u.com熱心網友回復:
有關型別推斷的確切程序,請參閱JLS 的第 18 章。值得注意的是,在這種情況下,實際上沒有運算式參與型別推斷,只有方法的型別引數參與。因此,您需要查看的最相關部分是§18.1.3的結尾:
當推理開始時,通常從型別引數宣告 P1、...、Pp 和關聯的推理變數 α1、...、αp 的串列中生成系結集。如下生成這樣的邊界集。對于每個 l (1 ≤ l ≤ p):
如果 Pl 沒有 TypeBound,則系結的 αl <: Object 出現在集合中。
否則,對于 TypeBound 中由 & 分隔的每個型別 T,邊界 αl <: T[P1:=α1, ..., Pp:=αp] 出現在集合中;如果這導致 αl 沒有合適的上限(只有依賴關系),那么界限 αl <: Object 也會出現在集合中。
對于Collections.emptyList,型別引數T沒有界限,所以第一種情況適用。現在T的上限為Object。然后解決了這個問題,并且T = Object根據§18.4 解決方案合并了另一個邊界,因此,T推斷為Object。
在一般情況下,(在簡單化JLS)為形式的陳述句f();,其中f與型別引數泛型方法T,所有的界限T(我們姑且稱之為B1 ... BN)被添加(如適當的上限)的系結集。該邊界集被決議為B1...Bn的最大下限 ( glb ),這就是推斷型別。
但是,唉,這實際上并不重要。型別引數在運行時都被擦除。因此,盡管規范說明了上述所有內容,但實際上編譯器可以很好地實作為在看到以下內容時根本不進行任何型別推斷:
Collections.emptyList();
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/323526.html
上一篇:Java擴展引數化類
