List、List
终于搞明白了<? extends T>与<? super T>的区别,网上很多文章说的都是错误的,下面讲下我的理解。
List、List
List :完全没有类型限制和赋值限定。
List


<? extends T>与<? super T>
List 最大的问题是只能放置一种类型,为了放置多种受泛型约束的类型,出现了 <? extends T>与<? super T> 两种语法。简单来说, <? extends T> 是Get First,适用于取出集合元素消费的场景;<? super T>是Put First,适用于生产集合元素为主的场景。
super T> : 里面放的是T或T的子类元素,注意理解, super T>是给集合设置了一个界限,不能往里放T以上的类型,但是可以安全的插入T或T子类。因为有上界,可以安全的插入上界类型的子类。但是读取出来时,因为无法确定具体是什么子类型,所以只能统一转为上届类型,泛型丢失。
extends T> :里面放的也是T或T的子类。那可能你会疑惑,这又什么区别呢?, extends T> 一般是用作方法的入参,用来限制传进来的参数必须只能是某个T类或其子类,这样我的方法可以统一向上强制转型为T进行处理。任何元素都不得添加进 extends T>集合内。记住 extends T>不能add元素进去。因为我们并不知道传进来的是什么具体的子类。
代码示例如下,以加菲猫、猫、动物为例,说明extends和super的详细语法差异



总之, extends T>的场景是put功能受限,可以读取元素,一般用来接收参数。
而 super T>是可以插入元素。
源码放上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public static void main(String[] args) {
List a1 =new ArrayList(); a1.add(new Object()); a1.add(new Integer(10)); a1.add(new String("string")); List<Object> a2 =a1; a2.add(new Object()); a2.add(new Integer(20)); a2.add(new String("string2")); a2.add(25); List<Integer> aint = new ArrayList<Integer>(); List<Object> a22 =aint; List<Integer> a3 = a1; a3.add(new Integer(20)); a3.add(new Object()); a3.add(new String("string2")); List<?> a4 = a1; a4.remove(0); a4.clear(); a4.add(new Object()); a4.add(new Integer(20)); a4.add(new String("string2")); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| class Animal{} class Cat extends Animal{} class Garfield extends Cat{}
public class AnimalCatGarfield { public static void main(String[] args) { List<Animal> animal = new ArrayList<Animal>(); List<Cat> cat = new ArrayList<Cat>(); List<Garfield> garfield = new ArrayList<Garfield>(); animal.add(new Animal()); cat.add(new Cat()); garfield.add(new Garfield()); List<? extends Cat> extendsCatFromAnimal = animal; List<? super Cat> superCatFromAnimal = animal; List<? extends Cat> extendsCatFromCat = cat; List<? super Cat> superCatFromCat = cat; List<? extends Cat> extendsCatFromGarfield = garfield; List<? super Cat> superCatFromGarfield = garfield; extendsCatFromCat.add(new Animal()); extendsCatFromCat.add(new Cat()); extendsCatFromCat.add(new Garfield()); superCatFromCat.add(new Animal()); superCatFromCat.add(new Cat()); superCatFromCat.add(new Garfield()); Animal object = (Animal) superCatFromCat.get(0); Cat object3 = (Cat) superCatFromCat.get(0); Garfield object4 = (Garfield) superCatFromCat.get(0); Animal catExtends3 = extendsCatFromCat.get(0); Object catExtends2 = extendsCatFromCat.get(0); Cat catExtends1 = extendsCatFromCat.get(0); Garfield cat2 = (Garfield) extendsCatFromGarfield.get(0); } }
|