再論<? extends T>和<? super T>
阿新 • • 發佈:2019-04-05
ati 知乎 abstract array http lean rand int https
參考:
https://www.cnblogs.com/drizzlewithwind/p/6100164.html
Java 泛型 <? super T> 中 super 怎麽 理解?與 extends 有何不同? - 胖君的回答 - 知乎
https://www.zhihu.com/question/20400700/answer/117464182
說得很清楚,但是有一處沒說明白(知乎上有人提出來了):
使用<? super Fruit>時,子類類型也接受:
Plate<? super Fruit> p2 = new Plate<>(new Fruit()); p2 = new Plate<>(new Food()); p2 = new Plate<>(new Fruit()); p2 = new Plate<>(new Apple()); // 這是個子類型
新寫一版,不引入Plate類,直接用JAVA自己的ArrayList類來做測試。
public interface List<E> extends Collection<E> { ... boolean add(E e); ... E get(int index); .... } public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{...}
定義三個類,Fruit->Apple->RedApple,聲明ArrayList,有如下現象:
import java.util.*; public class 泛型_通配符邊界2 { public static void main(String[] args) { ArrayList<Apple> p1 = new ArrayList<Apple>(); // 【震驚!裝得了蘋果,裝不了紅蘋果】 // ↓Type mismatch: // cannot convert from ArrayList<RedApple> to ArrayList<Apple> // ArrayList<Apple> p2 = new ArrayList<RedApple>(); } } class Fruit { } class Apple extends Fruit { } class RedApple extends Apple { }
解決方案就是
【1.<? extends Fruit>,定類型繼承關系的上界】
【2.<? super Apple>,確定類型繼承關系的下界】
解決方案如下,照著註釋看便是
package ah;
import java.util.*;
public class 泛型_通配符邊界2 {
public static void main(String[] args) {
ArrayList<Apple> p1 = new ArrayList<Apple>();
// 【震驚!裝得了蘋果,裝不了紅蘋果】
// ↓Type mismatch:
// cannot convert from ArrayList<RedApple> to ArrayList<Apple>
// ArrayList<Apple> p2 = new ArrayList<RedApple>();
// 【1.<? extends Fruit>,定類型繼承關系的上界:】
// 能裝Apple以及一切Apple的派生類
ArrayList<? extends Apple> p3 = new ArrayList<Apple>();
p3 = new ArrayList<RedApple>();
// ↓上層的類不接受
// Type mismatch:
// cannot convert from ArrayList<Fruit> to ArrayList<? extends Apple>
// p3 = new ArrayList<Fruit>();
// 【然而,extends是只讀的,不能寫入】
// p3.add(new Apple());
if (p3.size() != 0) {
Apple apple = p3.get(0);
}
// 【2.<? super Apple>,確定類型繼承關系的下界】
// 能裝水果以及一切水果的基類
ArrayList<? super Apple> p4 = new ArrayList<Apple>();
p4 = new ArrayList<Fruit>();
p4 = new ArrayList<Apple>();
// Type mismatch:
// cannot convert from ArrayList<RedApple> to ArrayList<? super Apple>
// p4 = new ArrayList<RedApple>();
// 【可讀可寫,讀出來的是Object類型】
p4.add(new RedApple());// 子類對象但是可以寫進入,因為默認向上轉型
Object object = p4.get(0);
System.out.println(object);
// 最後,JDK 7之後,ArrayList後面的<>裏什麽都不用寫
List<Apple> p2 = new ArrayList<>();
}
}
class Fruit {
}
class Apple extends Fruit {
}
class RedApple extends Apple {
}
再論<? extends T>和<? super T>