在上一篇文章中,我们介绍了泛型的基础知识点。详细可以参考文章:Java泛型入门必知的泛型详细知识点今天我们继续讲解泛型中另一个非常重要的概念,就是“小问号”——通配符!通配符的概念中除了用表示泛型外,还有一种形式是>。?被称为通配符。那么引入通配符的原因是什么呢?看下面的代码:voiddrive(){System.out.println("benzdrive");};}根据上面的代码,因为Benz是Car的子类,所以Carc=newBenz();成立,则ArrayListl=newArrayList();是否成立?我们可以看到编译时IDE直接报错,如下图:因此,我们得出Benz和Car有继承关系,并不代表List和List有继承关系关系。但是在真正的编码中,确实有这样的需求。希望泛型能够处理一定范围的数据类型,比如某个类及其子类。Java引入了这个?,也就是通配符的概念。有3种形式的通配符。>称为不合格的通配符。称为上限通配符。称为具有下限的通配符。无限通配符>通常与容器类结合使用。这?它实际上代表一个未知类型,所以操作涉及?必须与特定类型无关。这里的extends和super与泛型上下界中extends和super的概念是一致的。由于在上一篇文章中已经介绍过,这里不再赘述。解决了这样一个问题,代码如下:从上面的代码我们可以看出:不能编译,但是可以编译。可以编译,但是不能在里面存入l2。我们只能调用与类型无关的操作方法。代码如下:我们可以看到直接使用add方法报错!因为?未知。但是调用下面的方法是没有问题的。l2.get(0);l2.size();l2.iterator().next();这里需要了解一下,具有一定的写操作能力,代码如下:ArrayListl3=newArrayList<>();l3.add(newBenz());//成功l3.add(newCar());//编译失败,所以它提供了只读功能,也就是它添加具体类型元素的能力被去掉了,只留下与具体类型无关的功能。它不关心这个容器中加载的是什么类型的元素,它只关心元素的数量和容器是否为空。T和?之间的主要区别最后总结一下T和?的主要区别:区别1T代表判断的类型,这里的判断指的是运行时的判断。?表示一个未知类型,所以它涉及的操作基本和类型无关,所以jvm不需要为它判断类型,所以可以通过差异2进行编译,通过T保证泛型参数的一致性,如下两个参数的类型一致publicVoidtest(Listp1,Listp2)通配符不确定,所以下面的方法不能保证两个List的元素类型相同publicvoidtest(Listp1,Listp2)区别三:在实例化Class时,T应该换成具体的类。Class>是泛型类型,而?可以表示任何类型,所以主要用于声明的限制。比如我们可以这样声明://canpublicClass>clazz;//no,因为T需要指定类型publicClassclazzT;