请解释一下extends 和super 泛型限定符

    xiaoxiao2025-07-29  14

    https://blog.csdn.net/qq_40395278/article/details/88603655 https://www.cnblogs.com/drizzlewithwind/p/6100164.html 1、 <? extends T>限定参数类型的上界:参数类型必须是T或T的子类型 <? super T> 限定参数类型的下界:参数类型必须是T或T的超类型 2、 上界<? extends T>不能往里存,只能往外取。即<? extends Fruit>会使往盘子里放东西的set( )方法失效。但取东西get( )方法还有效。 因为:<? extends T>规定了变量eList的类型只能是T的子类,当add的时候,可能会出现add(A)中A的类型是T类型父类的情况。但是get的时候可以用T类型的变量接着。

    List<? extends Number> eList = null; eList = new ArrayList<Integer>(); Number numObject = eList.get(0); //语句1,正确 //Type mismatch: cannot convert from capture#3-of ? extends Number to Integer Integer intObject = eList.get(0); //语句2,错误 //The method add(capture#3-of ? extends Number) in the type List<capture#3-of ? extends Number> is not applicable for the arguments (Integer) eList.add(new Integer(1)); //语句3,错误 语句1:List<? extends Number>eList存放Number及其子类的对象,语句1取出Number(或者Number子类)对象直接赋值给Number类型的变量是符合java规范的。 语句2:List<? extends Number>eList存放Number及其子类的对象,语句2取出Number(或者Number子类)对象直接赋值给Integer类型(Number子类)的变量是不符合java规范的。 语句3:List<? extends Number>eList不能够确定实例化对象的具体类型,因此无法add具体对象至列表中,可能的实例化对象如下

    下界<? super T>不影响往里存,但往外取只能放在Object对象里。即使用下界<? super Fruit>会使从盘子里取东西的get( )方法部分失效,只能存放到Object对象里。set( )方法正常。 因为:<? super T>规定eList的类型是T类型的父类,所以get的时候不清楚到底是哪个父类,就只能用最大的父类Object类型接着。当add的时候不能addT的父类,因为不知道eList的类型到底是什么类型,但是可以addT和T的子类,因为eList中的类型肯定能接住T和T的子类。

    List<? super Integer> sList = null; sList = new ArrayList<Number>(); //Type mismatch: cannot convert from capture#5-of ? super Integer to Number Number numObj = sList.get(0); //语句1,错误 //Type mismatch: cannot convert from capture#6-of ? super Integer to Integer Integer intObj = sList.get(0); //语句2,错误 sList.add(new Integer(1)); //语句3,正确 语句1:List<? super Integer> 无法确定sList中存放的对象的具体类型,因此sList.get获取的值存在不确定性,子类对象的引用无法赋值给兄弟类的引用,父类对象的引用无法赋值给子类的引用,因此语句错误。 语句2:同语句1。 语句3:子类对象的引用可以赋值给父类对象的引用,因此语句正确。 总结:下界类型通配符get方法受限,但可以往列表中添加各种数据类型的对象。因此如果你想把对象写入一个数据结构里,使用 ? super 通配符。限定通配符总是包括自己。

    3、 上界<? extend Fruit> ,表示所有继承Fruit的子类,但是具体是哪个子类,无法确定,所以调用add的时候,要add什么类型,谁也不知道。但是get的时候,不管是什么子类,不管追溯多少辈,肯定有个父类是Fruit,所以,我都可以用最大的父类Fruit接着,也就是把所有的子类向上转型为Fruit。

    下界<? super Apple>,表示Apple的所有父类,包括Fruit,一直可以追溯到老祖宗Object 。那么当我add的时候,我不能add Apple的父类,因为不能确定List里面存放的到底是哪个父类。但是我可以add Apple及其子类。因为不管我的子类是什么类型,它都可以向上转型为Apple及其所有的父类甚至转型为Object 。但是当我get的时候,Apple的父类这么多,我用什么接着呢,除了Object,其他的都接不住。

    最新回复(0)