当前位置:首页>开发>正文

Java里的泛型加通配符的用法 java泛型与通配符

2023-07-19 07:37:11 互联网 未知 开发

 Java里的泛型加通配符的用法 java泛型与通配符

Java里的泛型加通配符的用法

感觉是有点问题,像是设计上的问题。

People p=new People()
List<? extends User> list=new ArrayList<People>()
list.add(p)

像你这个代码,如果list.add(p)加的不是一个People,那会怎么样呢?假设另一个类Man继承于User,且Man与People没从属关系。那么然后按照List<? extends User> list来理解,将Man加到list里面应该是没问题的吧。可是另一方面我们定义的list是一个new ArrayList<User>(),这样看的话把Man加到list里面貌似就呃掉了吧。

而按照freish的说法也是不那么对的样子。因为如果存在这么一个函数f(List<? extends Number> LN),在这里函数里,我们限制了输入的参数LN必须只能存放数字类Number,这样一个限制应该是很有用的吧,可以避免你把一个List<String>或者其他东西传给函数f()。如果按照freish的方法,我们把? extends Number直接写为Number的话,那么你f(new ArrayList<Integer>())这样写的话编译器会华丽丽的报错,所以这么改又是不对的。

在你这个问题里面的话,把list写出 List<? extends User> list 是没什么实际意义的,但是如果像是在上面函数f(List<? extends Number> LN)里的话确是有意义了。也就是说理论上来说,通配符是被设计成一个有用的东西的,也就是用来限定传入函数的参数的(或者赋值时来限定等号右边的)。而通过通配符来限定是某某某的子类或者超类在list这种容器应用的时候却产生了矛盾,也就是上面说的你本来只是想把People给加到list的,结果却一不小心把人家Man给加进来了。这样看来的话,java应该是考虑到这种情况了,所以就? extends User 成什么乱七八糟的 capture#105 of ? extends User类型了。泛型产生的原因就是当时的list这些容器能把任何类型的东西存进去又再拿出来(因为是Object),这样容易产生混乱。所以就产生了泛型来限制和检查类型。而这种限制却在这些特殊的情况下面产生了矛盾。

嗯,所以总结来说,你不能这么写代码,不能把要操作到泛型参数的方法的类声明为带有通配符的模式。还有一些例子看起来好似能通过编译的,实际确是不行的。比如说
class People<K,V> extends User{
void f(K k){System.out.println("f(K k)")}
void f(V v){System.out.println("f(V v)")}
}
在这里f有着两个不同类型参数K和V,看起来好像没事儿的样子。但是这是不能编译成功的。因为如果K是String而V也是String的时候,那么两个函数不就冲突了么?

java泛型与通配符

写E的是模板
而?是一种实例化,是不确定类型的实例化,直接写?,等同于? extends Object
boolean
removeAll(Collection c),是说,从自身(ArrayList)中移除,任意类型的集合的所有元素。
比如可以是Collection,也可以是其他。 而换成E,就被限定了。 原因是ArrayList是个模板类,使用的时候总要实例化,比如实例化为 ArrayList list 那么这个removeAll参数的类型也被实例化成Collection,这样是违背了设计的初衷了。

Java中什么是通配符

java中的通配符由?表示,应用场景是在方法的形参上使用,为了弥补泛型机制带来的参数传递问题,主要有三种通配符分类 无界通配:?,子类限定:? extends Object,父类限定:? super Integer。

java泛型无界通配符和原生的区别什么

无界通配符看起来意味着“任何事物”,因此使用无界通配符好像等价于使用原生类型。实际上,List表示“持有任何Object类型的原生List”,而List表示“具有某种特定类型的非原生List

java泛型通配符super问题

意思是一个T类或者是T类的父类,而add的时候加入的是属于T类的类型,而不是加入T类的未知父类类型。所以加入的元素必然要属于T类,明显这里的T类是B类的映射,而加入的只能是B类或者其子类。符合要求的只有D类,所以list.add(new B())是正确的。

最新文章