Java泛型

List、List<Object>、List<?> 的三者的区别以及 <? extends T>与<? super T> 的区别


 

List、List<Object>、List<?>

List :完全没有类型限制和赋值限定。
List<Object> :看似用法与List一样,但是在接受其他泛型赋值时会出现编译错误。
List<?>:是一个泛型,在没有赋值前,表示可以接受任何类型的集合赋值,但赋值之后不能往里面随便添加元素,但可以remove和clear,并非immutable(不可变)集合。List<?>一般作为参数来接收外部集合,或者返回一个具体元素类型的集合,也称为通配符集合。

import java.util.ArrayList;
import java.util.List;
public class TestArrayList {
    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<Object> 接受其他泛型赋值时,会报异常(因为在下面例子中List<Integer>不能转为List<Object>) List<Integer> aint = new ArrayList<Integer>(); List<Object> a22 =aint;//Type mismatch: cannot convert from List<Integer> to List<Object> List<Integer> a3 = new ArrayList<>(); a3.add(new Integer(20)); //下面两行编译出错,不允许增加非Integer类型进入集合 a3.add(new Object());//The method add(Integer) in the type List<Integer> is not applicable for the arguments (Object) a3.add(new String("string2")); //第四段:把a1引用赋值给a4,a4与a1的区别是增加了通配符 List<?> a4 = a1; //允许删除和清除元素 a4.remove(0); a4.clear(); //编译错误,不允许添加任何元素 a4.add(new Object());//The method add(capture#3-of ?) in the type List<capture#3-of ?> is not applicable for the arguments (Object) a4.add(new Integer(20)); a4.add(new String("string2")); } }

<? extends T>与<? super T>

List 最大的问题是只能放置一种类型,如果随意转变类型的话,就是破窗理论,泛型就失去了意义。

为了放置多种受泛型约束的类型,出现了 <? extends T>与<? super T> 两种语法。

  • <? extends T>:上界通配符(Upper Bounds Wildcards)

  • <? super T>:下界通配符(Lower Bounds Wildcards)


 

举例:继承关系:F->E->D->C->B

赋值

<? extends T>只能赋值T或T的子类集合;<? super T>只能赋值T或T的父类集合

ArrayList<B> b = new ArrayList<>();
ArrayList<C> c = new ArrayList<>();
ArrayList<D> d = new ArrayList<>();
// <? extends C>
list1 = b; // 报错
list1 = c;
list1 = d;
// <? super C>
list2 = b; 
list2 = c;
list2 = d; // 报错

add(),get()




posted @ 2021-09-29 15:16  忙碌了一整天的L师傅  阅读(51)  评论(0编辑  收藏  举报