千家信息网

Java中super与extends有什么区别

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"Java中super与extends有什么区别",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java中super与extends有什么区
千家信息网最后更新 2026年11月03日Java中super与extends有什么区别

本篇内容主要讲解"Java中super与extends有什么区别",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java中super与extends有什么区别"吧!

// compile error
// List appList2 = new ArrayList();
// appList2.add(new Fruit());
// appList2.add(new Apple());
// appList2.add(new RedApple());

List appList = new ArrayList();
appList.add(new Fruit());
appList.add(new Apple());
appList.add(new RedApple());

-------------------------------------------------------------------------------------------------

胖君

he who transplants sustains

1,200 人赞同了该回答

题主说的和是Java泛型中的"通配符(Wildcards)"和"边界(Bounds)"的概念。

  • :是指 "上界通配符(Upper Bounds Wildcards)"

  • :是指 "下界通配符(Lower Bounds Wildcards)"

1. 为什么要用通配符和边界?

使用泛型的过程中,经常出现一种很别扭的情况。比如按照题主的例子,我们有Fruit类,和它的派生类Apple类。

class Fruit {}class Apple extends Fruit {}


然后有一个最简单的容器:Plate类。盘子里可以放一个泛型的"东西"。我们可以对这个东西做最简单的"放"和"取"的动作:set( )和get( )方法。

class Plate{    private T item;    public Plate(T t){item=t;}    public void set(T t){item=t;}    public T get(){return item;}}


现在我定义一个"水果盘子",逻辑上水果盘子当然可以装苹果。

Plate p=new Plate(new Apple());


但实际上Java编译器不允许这个操作。会报错,"装苹果的盘子"无法转换成"装水果的盘子"。

error: incompatible types: Plate cannot be converted to Plate


所以我的尴尬症就犯了。实际上,编译器脑袋里认定的逻辑是这样的:

  • 苹果 IS-A 水果

  • 装苹果的盘子 NOT-IS-A 装水果的盘子

所以,就算容器里装的东西之间有继承关系,但容器之间是没有继承关系的。所以我们不可以把Plate的引用传递给Plate。

为了让泛型用起来更舒服,Sun的大脑袋们就想出了和的办法,来让"水果盘子"和"苹果盘子"之间发生关系。

2. 什么是上界?

下面代码就是"上界通配符(Upper Bounds Wildcards)":

Plate<? extends Fruit>


翻译成人话就是:一个能放水果以及一切是水果派生类的盘子。再直白点就是:啥水果都能放的盘子。这和我们人类的逻辑就比较接近了。Plate<? extends Fruit>和Plate最大的区别就是:Plate<? extends Fruit>是Plate以及Plate的基类。直接的好处就是,我们可以用"苹果盘子"给"水果盘子"赋值了。

Plate p=new Plate(new Apple());


如果把Fruit和Apple的例子再扩展一下,食物分成水果和肉类,水果有苹果和香蕉,肉类有猪肉和牛肉,苹果还有两种青苹果和红苹果。

//Lev 1class Food{}//Lev 2class Fruit extends Food{}class Meat extends Food{}//Lev 3class Apple extends Fruit{}class Banana extends Fruit{}class Pork extends Meat{}class Beef extends Meat{}//Lev 4class RedApple extends Apple{}class GreenApple extends Apple{}


在这个体系中,上界通配符 "Plate<? extends Fruit>" 覆盖下图中蓝色的区域。

3. 什么是下界?

相对应的,"下界通配符(Lower Bounds Wildcards)":

Plate<? super Fruit>

表达的就是相反的概念:一个能放水果以及一切是水果基类的盘子。Plate<? super Fruit>是Plate的基类,但不是Plate的基类。对应刚才那个例子,Plate<? super Fruit>覆盖下图中红色的区域。

4. 上下界通配符的副作用

边界让Java不同泛型之间的转换更容易了。但不要忘记,这样的转换也有一定的副作用。那就是容器的部分功能可能失效。

还是以刚才的Plate为例。我们可以对盘子做两件事,往盘子里set( )新东西,以及从盘子里get( )东西。

class Plate{    private T item;    public Plate(T t){item=t;}    public void set(T t){item=t;}    public T get(){return item;}}
4.1 上界不能往里存,只能往外取

会使往盘子里放东西的set( )方法失效。但取东西get( )方法还有效。比如下面例子里两个set()方法,插入Apple和Fruit都报错。

Plate p=new Plate(new Apple());//不能存入任何元素p.set(new Fruit());    //Errorp.set(new Apple());    //Error//读取出来的东西只能存放在Fruit或它的基类里。Fruit newFruit1=p.get();Object newFruit2=p.get();Apple newFruit3=p.get();    //Error

原因是编译器只知道容器内是Fruit或者它的派生类,但具体是什么类型不知道。可能是Fruit?可能是Apple?也可能是Banana,RedApple,GreenApple?编译器在看到后面用Plate赋值以后,盘子里没有被标上有"苹果"。而是标上一个占位符:CAP#1,来表示捕获一个Fruit或Fruit的子类,具体是什么类不知道,代号CAP#1。然后无论是想往里插入Apple或者Meat或者Fruit编译器都不知道能不能和这个CAP#1匹配,所以就都不允许。

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

public  List fill(T... t);

但通配符没有这种约束,Plate单纯的就表示:盘子里放了一个东西,是什么我不知道。

所以题主问题里的错误就在这里,Plate<? extends Fruit>里什么都放不进去。

4.2 下界不影响往里存,但往外取只能放在Object对象里

使用下界会使从盘子里取东西的get( )方法部分失效,只能存放到Object对象里。set( )方法正常。

Plate p=new Plate(new Fruit());//存入元素正常p.set(new Fruit());p.set(new Apple());//读取出来的东西只能存放在Object类里。Apple newFruit3=p.get();    //ErrorFruit newFruit1=p.get();    //ErrorObject newFruit2=p.get();

因为下界规定了元素的最小粒度的下限,实际上是放松了容器元素的类型控制。既然元素是Fruit的基类,那往里存粒度比Fruit小的都可以。但往外读取元素就费劲了,只有所有类的基类Object对象才能装下。但这样的话,元素的类型信息就全部丢失。

5. PECS原则

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

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

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

到此,相信大家对"Java中super与extends有什么区别"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

盘子 水果 东西 通配符 苹果 下界 方法 元素 就是 上界 容器 类型 编译器 编译 之间 例子 实际 内容 实际上 对象 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 伟宏互联网科技 广州万易互联网科技有限公司 科技赋能下的互联网金融 碳银互联网科技 上海致骋互联网科技 融势互联网科技 国外互联网科技网站 深圳市运趣互联网科技有限公司 互联网教育科技公司vipkid 以后互联网后是啥科技 昭通云南众福互联网科技有限公司 重庆互联网医院沙龙医盟信息科技 互联网科技大奖都有哪些公司 互联网科技如何创业 云鲸互联网络科技有限公司 互联网科技手机排行榜 科技信息时代互联网发展 互联网时代高科技布局 深圳互联网科技园地址 互联网大会出现的黑科技 互联网高科技股票 互联网科技股午盘股票涨跌 富国互联网科技创新基金 天速互联网络科技有限公司 特约风豹互联网科技为什么扣费 群盈汇互联网科技有限公司 江苏互联网智能科技软件 领航科技大厦互联网公司 2021世界互联网领先科技成果发布 华人运通互联网科技公司
0