2016-03-07 44 views
3

代碼示例#1:未選中投僅在泛型類型警告

public class Foo implements Cacheable { 
} 

public class Fooer { 
    void doSomething(Cacheable obj) { 
     Foo foo = (Foo) obj; //#1 
    } 
} 

代碼示例2:

public class GenericFooer<FooClass extends Cacheable> { 
    void doSomething(Cacheable obj) { 
     FooClass foo = (FooClass) obj; //#2 
    } 
} 

爲什麼我會得到一個「未鑄: '可緩存' 到 'FooClass' 「#2情況下警告,但不是#1情況下警告?這兩個案件對我來說看起來完全一樣。我是否錯過了某些東西,或者代碼檢查器有點壞了? PS:我正在使用InteliJ IDEA社區版。

PSS:我知道如何解決這個警告,唯一的問題是爲什麼它在這裏,如果它不在那裏。

+4

那麼在案例1中,你正在轉換爲實際類型。在情況2中,您將投射到一個類型參數,該參數在執行時不會被知道...... –

回答

1

在這兩種情況下,你都在做一些無法保證的事情。在實際確定它將是Foo之前​​,您將obj投射到Foo。那爲什麼不同的行爲?

在#1的情況下: 用cast(美孚)你告訴編譯器信任你那可緩存OBJ一定會富。所以編譯器只是檢查類層次並繼續。 (如果您嘗試在不同的類層次結構之間投射對象,則會出現錯誤) 但是,如果它不是Foo,則會在運行時拋出ClassCastException。

在#2的情況下: 泛型本質上被設計爲提供更嚴格的類型檢查。請參閱Java文檔: Java Generics

因此,編譯器確保爲您提供警告。

也看看泛型:類型擦除

+2

所以基本上唯一的原因是「如果您打擾使用泛型,請做好。」? – Arsen

+0

你可以這麼說。然而,你的錯誤在兩種情況下都是一樣的 - 做一些不能保證的事情。當您使用泛型時,它會突出顯示。 – theLearner

+0

我知道這一點。對我來說,這只是不合邏輯的,那就是警告不在#1,但在#2。 – Arsen