[英]How does polymorphism differ from generics in Java ArrayLists?
如果我有一個ArrayList<Shape>
,我的印象是在該列表中我可以存儲類Shape
對象或Shape
子類。
我還看到了很多關於ArrayList<T>
或ArrayList<?>
類的符號。 這些都是一樣的嗎? 一個T
超類及其所有子類都可以存儲,並且?
只是一個占位符?
基本上,它是怎么樣ArrayList<CLASSNAME>
從不同ArrayList<T>
你只是有一個字母。
首先,區別在於它是否是您想象的一個字母。 是否T
是通用參數的名稱。 如果您聲明一個方法,如:
public <T> void method()
而不是:
public void method()
或類似的類:
public class Whatever<T>
而不是:
public class Whatever
然后T
是一個通用參數。 然后,您可以在任何您想要的地方使用T
,就好像它是一個真正的類名,並且在編譯時將使用真實的類名替換T
但這不是它的最佳圖片,所以讓我們說T
的類型是傳遞給T
類型參數的任何類型。因此,在任何給定時刻, T
都有一個真正的類名稱值。
所以,之間的差ArrayList<T>
和ArrayList<Shape>
是ArrayList<T>
持有類型的對象T
,而ArrayList<Shape>
持有類型的對象Shape
。 訣竅是T
是傳遞給類型T
參數的任何類型,因此它可以變化。
免責聲明: T
型實際上並未隨時間而變化。 在大多數情況下,編譯器將其替換為Object
。 但是,編譯器擅長隱藏它,並且考慮T
更改是個好主意。
首先,ArrayList不能像這樣引用Shape的任何子類:
ArrayList<Shape> blah = new ArrayList<Square>
但你可以這樣做:
ArrayList<? extends Shape> blah = new ArrayList<Square>
多態性不適用於類型參數。 它僅適用於以下對象:
Collection<String> blah = new ArrayList<String>
但是你必須理解使用T. T的目的是為類和方法聲明一個類型參數。
這樣當你用參數T聲明一個類時:
public class ArrayList <T>
當類被實例化為對象時,T充當占位符。
所以在這種情況下:
ArrayList<String>
您正在使用ArrayList類中的String替換T.
順便說一句,你不應該使用T作為參數的類型。 因為T沒有真正定義,所以它只是一個占位符。
當您在創建ArrayList實例並將其與類型參數String關聯時,在聲明類型/類和ArrayList<String>
時表達ArrayList<T>
。
例如:
// class declaration
public class ArrayList<T> extends ... implements ... {
...
// Creating an arraylist of string
ArrayList<String> stringArray = new ArrayList<String>
您可以將泛型視為類型變量。 因此,而不是創建只適用於String的類:
public class MyArray {
String get(int index) { ... }
}
您可以創建一個適用於任意類型的數組類
public class MyArray<T> {
T get(int index) { .. }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.