2009-09-29 39 views
4

這裏是我的代碼:的Java:類型安全 - 選中投

Object[] data = GeneComparison.readData(files); 
MyGenome genome = (MyGenome) data[0]; 
LinkedList<Species> breeds = (LinkedList<Species>) data[1]; 

它給出了這樣的預警LinkedList的:

Type safety: Unchecked cast from Object to LinkedList<Species> 

爲什麼會抱怨鏈表,而不是MyGenome?

回答

3

因爲在這裏:

MyGenome genome = (MyGenome) data[0]; 

您沒有使用泛型

這裏

LinkedList<Species> breeds = (LinkedList<Species>) data[1]; 

您使用的是他們。

這只是一個警告,你是在數據數組中混合類型。如果你知道你在做什麼(我的意思是,如果第二個元素包含LinkedList),你可以忽略警告。

但更好的是有這樣一個對象:

class Anything { 
    private Object [] data; 
    public Anything(Object [] data) { 
     this.data = data; 
    } 
    public Gnome getGnome() { 
    ..... 
    } 
    public List<Species> getBreeds() { 
    ...... 
    } 
} 

,不得不返回正確的事情,正確的轉換之前,方法,所以你最終有:

Anything anything = new Anything(GeneComparison.readData(files)); 
MyGenome genome    = anything.getGnome(); // similar to data[0] 
LinkedList<Species> breeds = anything.getBreeds(); // similar to data[1]; 

裏面那些方法你必須做適當的轉換。

12

當您將非參數化類型(Object)轉換爲參數化類型(LinkedList)時,Java會發出類似的抱怨。這是告訴你,它可能是任何東西。它與第一次投射真的沒什麼兩樣,除非第一次會產生一個ClassCastException,如果它不是那種類型,但第二次不會。

這一切歸結爲類型擦除。運行時的LinkedList實際上只是一個LinkedList。你可以放入任何東西,它不會像第一個例子那樣產生ClassCastException。

往往擺脫這種警告,你必須做的是這樣的:

@SuppressWarning("unchecked") 
public List<Something> getAll() { 
    return getSqlMapClient.queryForList("queryname"); 
} 

其中的queryForList()返回一個列表(非參數),你知道的內容將是類的東西。

對此的另一方面是Java中的數組是covariant,這意味着它們保留運行時類型信息。例如:

Integer ints[] = new Integer[10]; 
Object objs[] = ints; 
objs[3] = "hello"; 

會拋出異常。但是:

List<Integer> ints = new ArrayList<Integer>(10); 
List<Object> objs = (List<Object>)ints; 
objs.add("hello"); 

是完全合法的。