返回顶部
首页 > 资讯 > 精选 >Java中?extendsT和?superT是什么
  • 416
分享到

Java中?extendsT和?superT是什么

2023-06-30 14:06:53 416人浏览 薄情痞子
摘要

本篇内容主要讲解“Java中?extendsT和?superT是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中?extendsT和?superT是什么”吧!? 通配符类型<?

本篇内容主要讲解“Java中?extendsT和?superT是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中?extendsT和?superT是什么”吧!

? 通配符类型

  • <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类;

  • <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object;

上界<? extends T>不能往里存,只能往外取

比如,我们现在定义:List<? extends T>首先你很容易误解它为继承于T的所有类的集合,你可能认为,你定义的这个List可以用来put任何T的子类,那么我们看下面的代码:

import java.util.LinkedList;import java.util.List;public class test {    public static void main(String[] args) {        List<? extends Father> list = new LinkedList<>();        list.add(new Son());    }}class Human{}class Father extends Human{}class Son extends Father{}class LeiFeng extends Father {}

list.add(new Son());这行会报错:The method put(Son) is undefined for the type List<capture#1-of ? extends Father>

List<? extends Father> 表示 “具有任何从Son继承类型的列表”,编译器无法确定List所持有的类型,所以无法安全的向其中添加对象。可以添加null,因为null 可以表示任何类型。所以List 的add 方法不能添加任何有意义的元素,但是可以接受现有的子类型List 赋值。

你也许试图这样做:

List<? extends Father> list = new LinkedList<Son>();list.add(new Son());

即使你指明了为Son类型,也不能用add方法添加一个Son对象。

list中为什么不能加入Father类和Father类的子类呢,我们来分析下。

List<? extends Father>表示上限是Father,下面这样的赋值都是合法的

   List<? extends Father> list1 = new ArrayList<Father>();   List<? extends Father> list2 = new ArrayList<Son>();   List<? extends Father> list3 = new ArrayList<LeiFeng>();

如果List<? extends Father>支持add方法的话:

  • list1可以add Father和所有Father的子类;

  • list2可以add Son和所有Son的子类;

  • list3可以add LeiFeng和所有LeiFeng的子类。

下面代码是编译不通过的:

list1.add(new Father());//errorlist1.add(new Son());//error

原因是编译器只知道容器内是Father或者它的派生类,但具体是什么类型不知道。可能是Father?可能是Son?也可能是LeiFeng,XiaoMing?编译器在看到后面用Father赋值以后,集合里并没有限定参数类型是“Father“。而是标上一个占位符:CAP#1,来表示捕获一个Father或Father的子类,具体是什么类不知道,代号CAP#1。然后无论是想往里插入Son或者LeiFeng或者Father编译器都不知道能不能和这个CAP#1匹配,所以就都不允许。

所以通配符<?>和类型参数的区别就在于,对编译器来说所有的T都代表同一种类型。比如下面这个泛型方法里,三个T都指代同一个类型,要么都是String,要么都是Integer。

public <T> List<T> fill(T... t);

但通配符<?>没有这种约束,List<?>单纯的就表示:集合里放了一个东西,是什么我不知道。

所以这里的错误就在这里,List<? extends Father>里什么都放不进去。

List<? extends Father> list不能进行add,但是,这种形式还是很有用的,虽然不能使用add方法,但是可以在初始化的时候一个Season指定不同的类型。比如:

List<? extends Father> list1 = getFatherList();//getFatherList方法会返回一个Father的子类的list

另外,由于我们已经保证了List中保存的是Father类或者他的某一个子类,所以,可以用get方法直接获得值:

List<? extends Father> list1 = new ArrayList<>();Father father = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。Object object = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。Human human = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。Son son = (Son)list1.get(0);

下界<? super T>不影响往里存,但往外取只能放在Object对象里

下界用super进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object。

//super只能添加Father和Father的子类,不能添加Father的父类,读取出来的东西只能存放在Object类里List<? super Father> list = new ArrayList<>();list.add(new Father());list.add(new Human());//compile error list.add(new Son());Father person1 = list.get(0);//compile error Son son = list.get(0);//compile error Object object1 = list.get(0);

因为下界规定了元素的最小粒度的下限,实际上是放松了容器元素的类型控制。既然元素是Father的基类,那往里存粒度比Father小的都可以。出于对类型安全的考虑,我们可以加入Father对象或者其任何子类(如Son)对象,但由于编译器并不知道List的内容究竟是Father的哪个超类,因此不允许加入特定的任何超类(如Human)。而当我们读取的时候,编译器在不知道是什么类型的情况下只能返回Object对象,因为Object是任何Java类的最终祖先类。但这样的话,元素的类型信息就全部丢失了。

PECS原则

最后看一下什么是PECS(Producer Extends Consumer Super)原则,已经很好理解了:

  • 频繁往外读取内容的,适合用上界Extends。

  • 经常往里插入的,适合用下界Super。

到此,相信大家对“Java中?extendsT和?superT是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: Java中?extendsT和?superT是什么

本文链接: https://lsjlt.com/news/329541.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中?extendsT和?superT是什么
    本篇内容主要讲解“Java中extendsT和superT是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中extendsT和superT是什么”吧! 通配符类型< exten...
    99+
    2023-06-30
  • Java中?extendsT和?superT的理解
    目录 通配符类型上界< extends T>不能往里存,只能往外取下界< super T>不影响往里存,但往外取只能放在Object对象里PECS原则总结 通...
    99+
    2024-04-02
  • Java中什么是BeanFactory和FactoryBean
    本篇内容主要讲解“Java中什么是BeanFactory和FactoryBean”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中什么是BeanFacto...
    99+
    2024-04-02
  • java和php是什么
    本篇内容介绍了“java和php是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!java是一种通用的面向对象编程语言,旨在生成可在任何地...
    99+
    2023-06-25
  • Java中封装和继承是什么
    这篇文章给大家分享的是有关Java中封装和继承是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一. 封装那封装是什么呢?在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接...
    99+
    2023-06-20
  • Java中volatile和synchronized区别是什么?
    不懂Java中volatile和synchronized区别是什么??其实想解决这个问题也不难,下面让小编带着大家一起学习怎么去解决,希望大家阅读完这篇文章后大所收获。volatile是变量修饰符,而synchronized则是作用于一段代...
    99+
    2023-05-31
    java volatile synchronized
  • java中int和integer的区别是什么?
    java中int和integer的区别 ● int是基本数据类型,int变量存储的是数值;Integer是引用数据类型,实际是一个对象,Integer存储的是引用对象的地址。 ● int默认值是0,Integer默认值是null; ● in...
    99+
    2021-09-17
    java教程 java int integer
  • java中if和while的区别是什么?
    java中if和while的区别是什么?while和if本身就用法不同,一个是循环语句,一个是判断语句。if 就是一个判断的,如果满足后面的条件就继续运行if语句里面的东西的,要是不满足就跳出来,执行else语句或执行下面的语句的 。whi...
    99+
    2021-03-09
    java教程 java if while
  • java中栈和堆的区别是什么
    Java栈Java 栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的Java栈,在这个Java栈中又会含有多个栈,这些栈帧是与每个方法关联起来的,每个运行一个方法就创建一个栈帧会含有一些“内部变量"(在方法内定...
    99+
    2019-01-17
    java入门 java 区别
  • java中set和list的区别是什么?
    Java中的集合共包含三大类,它们分别是Set(集),List(列表)以及Map(映射)。它们都处在java.util中并且都为接口。它们各自都有各自的实现类。下面给大家介绍一下set和list的区别,希望对大家有所帮助。java中set和...
    99+
    2020-08-03
    java入门 java set list
  • java中wait和sleep的区别是什么?
    sleep:sleep 方法属于 Thread 类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了 sleep方法之后,并不...
    99+
    2021-04-11
    java wait sleep
  • java中Overload和Override的区别是什么
    这篇文章主要为大家展示了“java中Overload和Override的区别是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java中Overload和Ov...
    99+
    2024-04-02
  • 在java中synchronized和ReentrantLock区别是什么
    java中synchronized和ReentrantLock区别:synchronized是关键字,而ReentrantLock是类。ReentrantLock比synchronized更灵活。ReentrantLock可以对获取锁的等待...
    99+
    2024-04-02
  • java中this和super的区别是什么
    java中this和super的区别是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、We...
    99+
    2023-06-14
  • Java中Integer和int的区别是什么
    这篇文章主要介绍Java中Integer和int的区别是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、基本概念(重要)Integer 是 int 的包装类,int 则是 java 的一种基本数据类型;Inte...
    99+
    2023-06-15
  • Java中super和extends的作用是什么
    Java中super和extends的作用是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。List< extends T>表示该集合中存在的都是类型T的子类...
    99+
    2023-06-20
  • Java中next()和nextLine()的区别是什么
    这期内容当中小编将会给大家带来有关Java中next()和nextLine()的区别是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Scanner scanner = n...
    99+
    2023-06-20
  • Java中的装箱和拆箱是什么
    本篇内容介绍了“Java中的装箱和拆箱是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录装箱拆箱==null总结装箱八大基本类型都有一...
    99+
    2023-06-20
  • Java中Exception和Error的区别是什么
    这篇文章主要介绍“Java中Exception和Error的区别是什么”,在日常操作中,相信很多人在Java中Exception和Error的区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中...
    99+
    2023-06-20
  • Java中SortedMap和NavigableMap的作用是什么
    本篇文章给大家分享的是有关Java中SortedMap和NavigableMap的作用是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、前言由于乱序的数据对查找不利,例如...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作