[問題] 請問泛型的問題

作者: jtorngl (Pedrosa go!)   2020-08-29 12:31:55
請問 Collection 不支援 covariance (還是該說泛型不支援 covariance)
所以 summary 只能傳入 List<Number> 的物件
而不能傳入 List<Integer>、List<Double>, ...
public double summary(List<Number> nums) {
double total = 0;
for (Number num : nums) {
total += num.doubleValue();
}
return total;
}
為了讓這段程式能達到類似 covariance 機制
所以會使用 wildcard
public double wildcardSummary(List<? extends Number> nums) {
double total = 0;
for (Number num : nums) {
total += num.doubleValue();
}
return total;
}
不過泛型使用 extends 一樣可以做到不是嗎
private <E extends Number> double genericsSummary(List<E> nums) {
double total = 0;
for (Number num : nums) {
total += num.doubleValue();
}
return total;
}
目前能想到的只有,wildcard 有 super 來達到 contravariance
但是泛型只支援 extends 而沒有支援 super
那如果沒有要 contravariance 的效果
有什麼情況是 wildcard 才能做到,而泛型還是不能編譯的?
目前看一些文章,在方法的參數,要限制參數型態邊界時
幾乎都是使用 List<? extends Number>
好像比較少看到 <E extends Number> ... List<E>
看了一下 JDK 的 List interface
boolean addAll(Collection<? extends E> c);
是因為限制的參數型態都是動態,才只能用 wildcard 嗎?
補充一下,問這個問題主要是,目前開始接觸 sonarcube 這類工具
對於程式會有很多規範,雖然目前還沒去看是否有泛型語法的 issue
只是想先問一下,實際開發時,是否在需要限制參數邊界時
一律使用 wildcard,而不要用泛型宣告
作者: ssccg (23)   2020-08-29 13:14:00
在你舉的method參數,只用在一個地方的情況下,兩個一樣https://docs.oracle.com/javase/tutorial/extra/generics/methods.html 官方文件是建議在這個情況下用wildcardwildcard才能做到的如你說的就是下限(super),另外就是不需要type parameter可以直接用在field、local variable而generic的type parameter可以用在多個參數,可有多個上限
作者: tw11509 (John-117)   2020-08-31 11:54:00
Producer Extends, Consumer Super 關鍵字,可以參考一下對我來說,通常不用去管泛型類別時,我會選擇用wildcard,例如:Collections#swap,交換List中的元素根本不需要知道裡面裝了什麼類別的元素

Links booklink

Contact Us: admin [ a t ] ucptt.com