[英]How to create a type safe generic array in java?
我想在java中創建一個通用數組,保持Java通常提供的類型安全性。
我正在使用此代碼:
class Stack<T> {
private T[] array = null;
public Stack(Class<T> tClass, int size) {
maximumSize = size;
// type unsafe
//array = (T[])new Object[maximumSize];
this.array = (T[])java.lang.reflect.Array.newInstance(tClass,maximumSize);
}
這個代碼類型安全嗎? 如果是這樣,為什么? 為什么如果它是類型安全我需要演員?
Array.newInstance(..)
方法的返回類型為Object
。 因此,您無法直接將其分配給除Object
之外的任何內容。 因此你需要一個演員。
該方法委托給一個native
方法
創建具有指定組件類型和長度的新數組
因此它創建了一個T
類型的數組。
類型安全,假設array
聲明為
T[] array;
,由Class<T>
參數和使用相同類型變量的強制轉換保證。
你應該添加
@SuppressWarnings("unchecked")
在您的源代碼中解釋上述原因的評論。 總是評論為什么一個警告你壓制的演員是安全的。
由於原始的Class對象,它不是類型安全的。 例如,我可以通過以下方式創建一個新的Stack:
new Stack<Boolean>(boolean.class, 10);
編譯器可以,但拋出異常,因為boolean.class
是一個Class<Boolean>
而boolean[]
不能轉換為Boolean[]
。
您展示的替代方案已注釋掉:
array = (T[])new Object[size];
實際上有些類型安全的,但出於不同的原因:是由於擦除。 例如,您不能將new Object[size]
轉換為Number[]
,但是數組中的轉換不會發生。 它會在一段時間后發生,就像從方法中返回數組元素一樣(在這種情況下元素被轉換)。 如果您嘗試執行某些操作(例如將數組返回到對象外部),則會引發異常。
通常,解決方案不是一般地鍵入數組。 相反,做這樣的事情:
class Stack<E> {
Object[] array = new Object[10];
int top;
void push(E elem) {
if(top == array.length)
array = Arrays.copyOf(array, array.length * 2);
array[top++] = elem;
}
E pop() {
@SuppressWarnings("unchecked")
E elem = (E)array[--top]; // type safe cast
array[top] = null;
return elem;
}
}
上面的強制類型是類型安全的,因為你只能將E
推入數組。 JDK Stack(擴展Vector)和ArrayList都以這種方式工作。
如果要使用newInstance
,則必須拒絕原語,因為無法一般地表示它們:
Stack(Class<T> tClass, int size) {
if(tClass.isPrimitive())
throw new IllegalArgumentException();
// ...
}
由於Array.newInstance
返回一個Object
它需要一個Array.newInstance
。 在這種情況下,編譯器將始終發出警告。 這是泛型的限制。
我們知道在編譯時檢查泛型所以,我的朋友java.lang.reflect.Array.newInstance(tClass,size); 返回對象並輸入類型,如果數組不是T []類型,則可能存在編譯時錯誤
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.