我正在瀏覽java 語言規范,看到了這種撰寫創建者的方式:
Creator:
NonWildcardTypeArguments CreatedName ClassCreatorRest
在普通代碼中:
new <Integer> String("1");
// or
new <String,Integer> Integer(5);
//or
new <Constructor,String,Integer> ArrayList<String>(5);
在我能想到的每個例子中,就我所知,類串列沒有用。當 new 關鍵字之后的型別串列起作用時,您能否舉個例子。
uj5u.com熱心網友回復:
除非您遇到型別變數建構式的極其奇特的java 語法建構式,否則此功能無效。本質上,你永遠不應該這樣做。它是為了語言完整性而存在的,可能永遠不應該被添加到 java.lang.
您可以在類上放置型別引數定義,這是最常見的模式。例如,ArrayList有一個型別變數;宣告如下:
class ArrayList<E> implements List<E> { ... }
第一個<E>宣告有一些E沒有邊界的型別。然后立即使用它(第一個<E>和第二個<E>看起來相同,但一個宣告型別 var,另一個是型別 var 用法,因此它們完全不同。到目前為止一切順利。
但是您也可以直接在方法上宣告它們。例如:
public static <E> coalesce(E... items) {
for (E item : items) if (item != null) return item;
return item;
}
可以使用任意數量的物件參考呼叫此方法,并將回傳第一個不是null的物件參考,并且呼叫的型別將是所有引數之間的公分母。換句話說,這將編譯:
String x = coalesce(null, someString, "defaultValue");
而如果我們寫了它:
public static Object coalesce(Object... items) {
for (Object item : items) if (item != null) return item;
return item;
}
然后,雖然coalesce(null, someStringRef, "default")顯然肯定會回傳 a String,但編譯器不知道這一點,因此String x = coalesce(..)不會編譯。你必須注入一個演員。泛型的重點是不必這樣做。
現在回答你的問題
這個相同的特性(方法型別引數)可用于建構式:
public class Example<T> {
public <A> Example(A first, A second) {
}
}
是合法的java。試圖想出您想要建構式泛型的情況是極其困難的。建構式沒有回傳型別,重點是 typeparam 只需要建構式,一旦你完成它就停止所有相關性(如果它與實體本身相關,你會把它放在型別上,就像<E>上面的例子一樣)。因此,為什么您從未在 Java 代碼中有效地看到它。然而,如果您要撰寫它,并且您不想javac推斷泛型,而是想對其進行明確說明,那么您正在閱讀的語法就是您將如何做到這一點:
new <String>Example<Integer>("a", "b");
將呼叫該建構式并強制A成為String和T成為Integer。
JLS 中有大量奇怪且令人困惑的結構,但沒有人使用過。因此,通讀 JLS 通常不是一個好主意,您會學到一些東西,但這是一種非常低效的學習方式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/383602.html
