2012-01-23 37 views
4

當我投來E[](類參數),它需要我補充爪哇 - 鑄造到E []

@SuppressWarnings("unchecked") 

例如:

E[] anArray = (E[]) new Object[10]; 

我應該做不同的東西,還是應該是這樣?

感謝

+0

@Mehrdad爲什麼要使用C#? – Stripies

+0

哈哈這是一個笑話,旨在解決這個問題(因爲'新T []'完全可以在C#中)...並不意味着你認真對待它。:) – Mehrdad

+0

@Mehrdad我想通了,但我不喜歡C#,因爲只能在Windows上使用它,但那不是重點。 – Stripies

回答

4

這是正確的。想象一下:

Object[] o = new Object[10]; 
o[0] = new A(); // A is not a subclass of E 
E[] e = o; // Now you have broken the type system: e[0] references something that is not an E. 

它的工作方式,你必須顯式強制轉換,以便讓編譯器忽略這種可能性。

2

它應該做的事情,因爲那type erasure

爲了避免以抑制警告,你能做的唯一的事情就是用List<E>(或類似Collection)。

+0

@Downvoter爲什麼? – Jeffrey

+0

據我所知,類型刪除不適用於數組。請參閱http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.8 – gpeche

+0

另請參閱http://docs.oracle.com/javase/7/docs/api/java/lang /Class.html#getComponentType%28%29。這種類型的擦除不可能。 – gpeche

2

是的,你應該做的是這樣,因爲我們不能初始化泛型的數組是這樣的:

E[] array = new E[10]; // Compile error 

你真的這樣做,你寫的。我無法知道。


另一種方法是使用對象數組(而不是E)。你可以看到,在Java API開發人員做的也是這樣的ArrayList類中:

/** 
* The array buffer into which the elements of the ArrayList are stored. 
* The capacity of the ArrayList is the length of this array buffer. 
*/ 
private transient Object[] elementData; 

,他們根本初始化數組是這樣的:

elementData = new Object[size]; 

而且無處不在,他們使用它,他們投的陣列內容:

/** 
* Returns the element at the specified position in this list. 
* 
* @param index index of the element to return 
* @return the element at the specified position in this list 
* @throws IndexOutOfBoundsException {@inheritDoc} 
*/ 
public E get(int index) { 
    RangeCheck(index); 

    return (E) elementData[index]; 
} 

我真的不知道,但我認爲第一種方法更快,因爲在運行時不需要鑄造。我想,Java VM會花費一些時間來鑄造它。我爲什麼這麼想?正因爲如此,在運行時提供了一個錯誤:

Integer i = new Integer(34); 
Object o = i; 
String s = (String) o; // Runtime error 

因此,這意味着虛擬機真正檢驗它是否一個字符串。但事實上,編譯器類型擦除讓我覺得它沒有任何區別。有人可以澄清嗎?

+0

*聲明一個泛型類型的數組不是問題。 'E []數組;'完全沒問題。 –

+0

@ TomHawtin-tackline:好的,我明白了,我將編輯:D –

+0

運行時遲早會執行一個運行時類,並在適當的時候拋出ClassCastException。這不是C/C++世界及其未定義的行爲。 – gpeche

3

您應該閱讀Effective Java書。總之,不可能確切知道你的正確行爲方式是因爲我們不知道你在做什麼,但通常你不應該壓制這個警告。所以最有可能的解決方案是使用類型安全的泛型集合而不是數組。

+0

使用'ArrayList'作爲例子,它抑制了這個警告,那麼在數組上使用'ArrayList'會怎樣? – Stripies

+0

看@gpeche說什麼。數組不是類型安全的。這只是泛型的工作方式 - 編譯器不能確保你正確地處理它們。當使用泛型ArrayList <>(而不是未經檢查的ArrayList!)時,您將停留在泛型類型的擦除世界中,編譯器仍然可以跟蹤所有類型。 –

+0

但'ArrayList <>'也使用不安全的方法。下面是從'的ArrayList <>' @SuppressWarnings( 「未登記」) ÈelementData中(INT指數){ 返回(E)elementData中[索引]的方法; } – Stripies