2011.03.07 Java泛型通配符

1、通配符提供了使用的靈活性,但對修改卻做出了限制
像平常一樣,要得到使用通配符的靈活性有些代價。這個代價是,現在像shapes中寫入是非法的。比如下面的代碼是不允許的:

public void addRectangle(List<? extends Shape> shapes) {

shapes.add(0, new Rectangle()); // compile-time error!

}

你應該能夠指出爲什麼上面的代碼是不允許的。因爲shapes.add的第二個參數類型是? extends Shape ——一個Shape未知的子類。因此我們不知道這個類型是什麼,我們不知道它是不是Rectangle的父類;它可能是也可能不是一個父類,所以這裏傳遞一個Rectangle不安全。

2、什麼時候使用通配符 什麼時候使用泛型方法

讓我們先看看Collection庫中的幾個方法。

public interface Collection<E> {

boolean containsAll(Collection<?> c);

boolean addAll(Collection<? extends E> c);

}

我們也可以使用泛型方法來代替:

public interface Collection<E> {

<T> boolean containsAll(Collection<T> c);

<T extends E> boolean addAll(Collection<T> c);

// hey, type variables can have bounds too!

}

但是,在 containsAll 和 addAll中,類型參數T 都只使用一次。返回值的類型既不依賴於類型參數(type parameter)也不依賴於方法的其他參數(這裏,只有簡單的一個參數)。這告訴我們類型參數(type argument)被用作多態(polymorphism),它唯一的效果是允許在不同的調用點,可以使用多種實參類型(actual argument)。如果是這種情況,應該使用通配符。通配符就是被設計用來支持靈活的子類化的,這是我們在這裏要強調的。

泛型函數允許類型參數被用來表示方法的一個或多個參數之間的依賴關係,或者參數與其返回值的依賴關係。如果沒有這樣的依賴關係,不應該使用泛型方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章