簡體   English   中英

如何在java中創建一個類型安全的通用數組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM