簡體   English   中英

我的通用方法中的強制轉換是否安全?

[英]Is this cast in my generic method safe?

我的項目中的代碼如下所示:

public interface Bar<T extends Foo<?>> {
 //...
}

public class MyFoo implements Foo<String> {
    private List<Bar<Foo<String>> barFoo = ...

    public <U extends Foo<String>> boolean addBar(Bar<? extends U> b) {
        barFoo.add((Bar<Foo<String>>) b); //safe cast?
    }

}

Eclipse為addBar中的addBar提供了警告,表明addBar是不安全的。 但是,我是否正確假設投射不會因為我對類型參數施加的限制而拋出,因此投射確實安全?

不一般。

假設Bar有一個方法void get(T value) ,並且有兩個實現Foo<String>MyFooYourFoo 現在假設調用者在類型為Bar<MyFoo>的值上調用addBar 這有效:當U = Foo<String> ,我們有Bar<MyFoo>Bar<? extends U>的子類型Bar<? extends U> Bar<? extends U> 現在我們將該值轉換為Bar<Foo<String>>

現在如果Bar沒有接受T作為參數的方法,那就沒問題了。 但是假設它有一個方法void process(T value) 我們調用的實現有T = MyFoo ,所以它只有一個process(MyFoo value)方法。 但是,一旦我們將它轉​​換為Bar<Foo<String>> ,我們可能會用YourFoo調用它。 這是非法的。

在黑暗中刺傷,但我懷疑你真正想做的是將barFoo聲明為List<? extends Bar<? extends Foo<String>> List<? extends Bar<? extends Foo<String>> List<? extends Bar<? extends Foo<String>>

這不是一個安全的演員。 Eclipse是對的。

想象一下,你有一個擴展Foo的類MyFoo ,你傳入了一個Bar<MyFoo<String>>現在,當只編譯了myMethod(MyFoo x)簽名時, Bar一些方法帶有myMethod(Foo x)簽名,因此方法查找會失敗的。

鑄造是不安全的,因為雖然U延伸Foo<String> ,它不是 (必須的),該案Bar<U>延伸Bar<Foo<String>> 事實上, Bar<U>只會在它們是相同的東西時擴展Bar<Foo<String>> ,即當UFoo<String>

直覺上,似乎(例如) List<String>應該是List<Object>的子類型,但這不是泛型的工作方式。 List<String>List<? extends Object>的子類型List<? extends Object> List<? extends Object> ,但它不是 List<Object>的子類型。 (考慮像Comparable<T>這樣的例子可能更有意義: Comparable<String>意味着“可以與任何String進行比較,而Comparable<Object>意味着”可以與任何Object進行比較。)應該清楚可Comparable<String>不應該是Comparable<Object>的子類型。)

[...]演員不會扔[...]因此演員確實安全嗎?

我認為你誤解了警告的性質。 Eclipse警告你, 即使應該這樣做,這個演員也不會拋出,這實際上是為什么它不安全。 例如,這段代碼:

final Object o = Integer.valueOf(7);
final String s = (String) o;

是非常安全的,因為演員會拋出異常。 但是這段代碼:

final List<?> wildcardList = new ArrayList<Integer>(Integer.valueOf(7));
final List<String> stringList = (List<String>) wildcardList;

不安全的 ,因為運行時無法檢查stringList (由於擦除),因此它不會拋出異常,即使它是錯誤的: stringList現在是一個List<String>其第一個元素是Integer類型。 (接下來會發生什么事情,當您嘗試對該元素執行某些操作時,您可以獲得自發的ClassCastException 。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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