我想學習java泛型。我寫了一個方法:爲什麼調用不同類型的泛型方法會導致編譯錯誤?
public <T> T Gmethod(T a,Collection<T> list){
return a;}
雖然調用這個與Gmethod("A",list);
是好的,其中的列表是Object
類型,
但稱這是與Gmethod(new Object(),list);
其中列表是String
類型是錯誤, 爲什麼呢?
我想學習java泛型。我寫了一個方法:爲什麼調用不同類型的泛型方法會導致編譯錯誤?
public <T> T Gmethod(T a,Collection<T> list){
return a;}
雖然調用這個與Gmethod("A",list);
是好的,其中的列表是Object
類型,
但稱這是與Gmethod(new Object(),list);
其中列表是String
類型是錯誤, 爲什麼呢?
具有
<T> T method(T a, Collection<T> list) { return a; }
並用
Collection<Object> list = new LinkedList<>();
method("A", list);
調用它會導致編譯器推斷出類型Object
的類型變量T
,如list
是Collection<Object>
類型。變量a
的類型是String
,它是Object
的子類型。所以這個方法調用是允許的。
調用帶
Collection<String> list = new LinkedList<>();
method(new Object(), list);
該方法將再次導致編譯器推斷該類型變量T
類型對象,如現在a
是Object
類型。因此,編譯器請求參數list
的參數爲Collection<Object>
(或子類型)類型。 但Collection<String>
不是Collection<Object>
的子類型。所以編譯器不允許這個方法調用。
絕對正確的仿製藥難倒「<...>但集合
當你有一個參考T
實際的類可以是T或一個子類。當你有一個<T>
它必須是那個類,只有那個類。這是必需的,因爲它是引用的容器,並且修改此容器可以更改原始容器。這不會在簡單參考中發生,因爲它是作爲副本傳遞的。
引用是按值複製的。
String a = "hi";
Object b = a;
b = new Object(); // no problem as `a` is not changed by this.
但是對於容器來說,這不能很好地工作,因爲只有容器的引用被複制,而不是容器本身。
List<String> a = new ArrayList<>();
a.add("hi");
List<Object> b = (List) a; // compiler warning.
b.add(new Object()); // alters `a` in an incorrect way.
a.get(1); // ClassCastException oops.
請您詳細說明一下。 –
@NarendraPathai希望更清楚。 –
+1是的我現在明白了。我也提供了我的理解視角。你能否也請通過我的答案來驗證我的理解。我會很感激。謝謝。每一個新的一天,說這個我得到某種方式:( –
正如@Seelenvirtuose和@Peter Lawrey在他們的回答中所建議的那樣,這是編譯器爲您做的Type Inference。
要測試的編譯器結合Object
第一個電話試試這個,
class Main{
public static void main(String[] args){
Collection<Object> listOfObject = new ArrayList<>();
Main.<String>method("a",listOfObject); //compile time error here
}
public static <T> T Gmethod(T a, Collection<T> coll){
return a;
}
}
你說,「集合
@Seelenvirtuose'編譯器請求所有參數爲相同類型或方法參數的子類型.'是子類型還是超類型?首先選擇超類型。我誤解了嗎? –
在這兩種方法調用中,編譯器推斷爲T的類型爲Object(首先,這是因爲_list_的類型爲Collection
您正在試圖通過兩種不同的類型,所以這類型你想成爲的T參數? – solvator