java泛型extends和super详解

首先,Java有泛型这一个概念,是为了初衷是为了保证在运行时出现的错误能提早放到编译时检查。有了这个前提,再来看看题主的问题。

// 编译会报错

// List extends Fruit> appList2 = new ArrayList();

// appList2.add(new Fruit());

// appList2.add(new Apple());

// appList2.add(new RedApple());

List super Fruit> appList = new ArrayList();

appList.add(new Fruit());

appList.add(new Apple());

appList.add(new RedApple());

假设现在有这么一个类的继承树,Plant -> Fruit -> Apple -> RedApple。

List extends Fruit> appList2的意思,是一个列表,这个列表里面的元素是Fruit的某个子类T,那么在从appList2中取出一个元素时,编译器会自动把这个元素转型为T。那么现在假设T是RedApple,很显然你往这样一个appList2中add一个Apple类型的元素,取出后转型为RedApple必然会失败;同样的情况如果T是Apple,你add一个Fruit类型的元素,取出后转型为Apple,也会抛出异常。也就是说,编译器会把列表中取出的元素转型为某种类型,但编译器不确定这种转型是不是会成功,即在不保证运行时能顺利进行,因此就不允许你add任何类型的元素。

再来看看List super Fruit> appList,这个列表的元素都是Fruit的父类T,也就是说当你从这个列表中get一个元素时,编译器会自动加一句转型为T的代码。好,现在你往appList中add一个Apple类型的元素,取出时转型为T,由于T是Apple的父类,向上转型没有问题;加一个RedApple类型的元素,也一样不会有问题。也就是说,只要保证你往appList中添加的元素是Fruit的子类,编译器就可以保证在转型为T时不会抛出异常。因此第二种写法可以过编译。

List :”存的时候只能选一个类型。“

List extends Fruit> 意思: List中所有元素都是Fruit的子类(包含本身),

List super Fruit> 意思: List中所有元素都是Fruit的父类(包含本身)

1、List extends Fruit>

假设:Fruit有子类A、B、C 那么 list.add(A);list.add(B);list.add(C);显然错误(不能存多个类)。

虽然我们现在看的是ABC3个类就会问为什么会把不同类型的存进去,我这样存不就好了。list.add(A); list.add(A); 其实这也是错误的,因为在运行之前他可不知道你到底add进去的东西是什么类型,是一样还是不一样,因实例化的时候是 ? 待定。为了避免类型不同的情况,所以会编译不通过。

2、List super Fruit>

假设:Fruit有子类A、B、C 那么 list.add(A); list.add(B); list.add(C); 这却是可以的,为什么呢:

因为他是这么存的:list.add((Fruit)A); list.add((Fruit)B); 自动强转了。因为小转大是隐性的,大转小才是强转需要加类型。

那这里为什么又不能存Fruit的父类呢? 因为 见假设1,它是?号,类型代表待定,不跑起来他也不知道你到底存的什么。所以我们能手动add()进去的数据都必须是绝对安全的(最低级父类:本身)才能通过。所以直接add父类也是不行的。

来个复杂的例子

>

首先这是运用了java的泛型

1、extends后面跟的类型如表示泛型的上限

import java.util.*;

class Demo{}

public class Test{

public static void main(String[] args) {

Demo p = null; // 编译正确

//这里因为ArrayList是AbstractList的子类所以通过

//如果改为Demo p = null;就会报错这样就限制了上限

}

}

2、同样的super表示泛型的下限

3、>这里来分析T表示任意字符名,extends对泛型上限进行了限制即T必须是Comparable super T>的子类,然后 super T>表示Comparable<>中的类型下限为T!这样来看一段代码辅助理解

import java.util.GregorianCalendar;

class Demo>{}

public class Test1{

public static void main(String[] args) {

Demo p = null; // 编译正确

}

}

这个可以理解为>是可以运行成功的!因为Calendar为GregorianCalendar 的父类并且GregorianCalendar 实现了Comparable,可查看api!.

如果是如下代码则运行不成功

import java.util.GregorianCalendar;

class Demo>{}

//这里把? super去掉了

public class Test{

public static void main(String[] args) {

Demo p = null;

}

}

编译会报错!因为>相当于>但是GregorianCalendar并没有实现Comparable而是实现的Comparable,这里不在限制范围之内所以会报错!

总结

extends/super分别是泛型的上下界(含)。

对T的约束是Comparable的子类,对Comparable中泛型的约束是,至少是T的父类。

最后

最后提供一个完整的例子,帮助各位理解。

public class SupperDemo03{

interface Animal{

}

static class EagleFish extends Bird{

}

static class Bird implements Animal{

}

static class Fish>{

}

public static void main(String[] args) {

Fish fish = new Fish<>();

}

}

java泛型extends_java泛型extends和super详解相关推荐

  1. Java学习第十二天<封装详解><继承><super详解><方法重写><多态>

    封装详解 //类 public class Student {//名字 学号 性别 属性私有(new 以后不能赋值)private String name;private int id;private ...

  2. java关键字super指什么_java 关键字super详解及用法

    java 关键字super详解 一.super关键字 在JAVA类中使用super来引用父类的成分,用this来引用当前对象,如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对 ...

  3. Java中super详解

    目录 Java中super详解 super的作用: 1.     通过super可以访问父类的构造方法 2.   通过super可以访问父类的属性(非私有) 3.        通过super可以访问 ...

  4. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  5. Java经典面试题整理及答案详解(八)

    简介: Java经典面试题第八节来啦!本节面试题包含了进程.线程.Object类.虚拟内存等相关内容,希望大家多多练习,早日拿下心仪offer- 了解更多: Java经典面试题整理及答案详解(一) J ...

  6. Super详解(重点)

    Super详解(重点) super注意点; 1. super调用父类的方法,必须在构造方法的第一个2. super必须只能出现在子类的方法或者构造方法中!3. super和this 不能同时调用构造方 ...

  7. 把java文件打包成.jar (jar命令详解)

    把java文件打包成.jar (jar命令详解) 先打开命令提示符(win2000或在运行框里执行cmd命令,win98为DOS提示符),输入jar Chelp,然后回车(如果你盘上已经有了jdk1. ...

  8. Java垃圾回收(GC)机制详解

    Java垃圾回收(GC)机制详解 转自:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因 ...

  9. java文件打包jar文件_把java文件打包成.jar (jar命令详解)

    把java文件打包成.jar (jar命令详解) 先打开命令提示符(win2000或在运行框里执行cmd命令,win98为DOS提示符),输入jar Chelp,然后回车(如果你盘上已经有了jdk1. ...

最新文章

  1. AMD64,linux-64bit,ARM64,linux-Aarch64和windows 64bit
  2. NSArray和NSMutableArray
  3. 计算机辅助设计的发展及应用,计算机辅助设计的发展与应用
  4. 45 MM配置-采购-条件-定价过程-定义定价计算方案
  5. 十年 | 在Java开发做了10年后,才学会此绝招,用于颠覆Java应用
  6. 腾讯发布企鹅号“达人计划”清退公告 清退后当月结算将被取消
  7. rocketmq linux环境下载地址,Linux下RocketMQ下载安装教程
  8. arm linux下交叉编译valgrind工具进行内存泄露检测和性能分析
  9. 报错:bash: pip: command not found
  10. 出现”/var/lib/mysql/mysql.sock“不存在的解决方法
  11. 大数据统计分析架构-netty部分
  12. vue 3 的devtools beta 版离线下载
  13. 【说透区块链系列】一文读懂什么是Web 3.0
  14. Windows下部署ubuntu16.04+anaconda2.7+tensorflow
  15. 链行动之精选案例——区块链解决四大痛点 福费廷结合案例逐步落地
  16. ARM Cortex-M3内核结构
  17. python输入三角形三条边长_python问题:输入三角形的三条边a,b,c,判断此三边是否可以构成三角形。等边、等腰、直角三角形?...
  18. python 矩阵类型转换_Python 矩阵转置的几种方法小结
  19. 什么才是人工智能未来发展的关键?
  20. FCC学习记录——使用 sort方法按字母顺序给数组排序

热门文章

  1. GC日志解读,这次别再说看不懂GC日志了
  2. vue ssr 实践
  3. 从零单排力扣周赛_周赛273
  4. DC48V电源浪涌不再难
  5. (学习)基于STM32的PWM控制直流电机转速(CubeMX+HAL库)
  6. Laya贝塞尔运动(金币获取运动)
  7. Dcs系统工程师站是服务器吗,DCS工程师站(ES)管理规定(转)
  8. DataTable 自定义搜索条件 _ 自定义查询参数
  9. 乐鑫ESP32-C3模组选型
  10. Micro SD卡(TF卡)封装和原理图总结