参考:

https://www.cnblogs.com/drizzlewithwind/p/6100164.html

Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同? - 胖君的回答 - 知乎

https://www.zhihu.com/question/20400700/answer/117464182

说得很清楚,但是有一处没说明白(知乎上有人提出来了):

使用<? super Fruit>时,子类类型也接受:

		Plate<? super Fruit> p2 = new Plate<>(new Fruit());
p2 = new Plate<>(new Food());
p2 = new Plate<>(new Fruit());
p2 = new Plate<>(new Apple()); // 这是个子类型

新写一版,不引入Plate类,直接用JAVA自己的ArrayList类来做测试。

public interface List<E> extends Collection<E> {
...
boolean add(E e);
...
E get(int index);
....
}
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable{...}

定义三个类,Fruit->Apple->RedApple,声明ArrayList,有如下现象:

import java.util.*;
public class 泛型_通配符边界2 {
public static void main(String[] args) {
ArrayList<Apple> p1 = new ArrayList<Apple>();
// 【震惊!装得了苹果,装不了红苹果】
// ↓Type mismatch:
// cannot convert from ArrayList<RedApple> to ArrayList<Apple>
// ArrayList<Apple> p2 = new ArrayList<RedApple>();
}
}
class Fruit {
}
class Apple extends Fruit {
}
class RedApple extends Apple {
}

解决方案就是

【1.<? extends Fruit>,定类型继承关系的上界】
【2.<? super Apple>,确定类型继承关系的下界】

解决方案如下,照着注释看便是

package ah;
import java.util.*;
public class 泛型_通配符边界2 {
public static void main(String[] args) {
ArrayList<Apple> p1 = new ArrayList<Apple>();
// 【震惊!装得了苹果,装不了红苹果】
// ↓Type mismatch:
// cannot convert from ArrayList<RedApple> to ArrayList<Apple>
// ArrayList<Apple> p2 = new ArrayList<RedApple>();
// 【1.<? extends Fruit>,定类型继承关系的上界:】
// 能装Apple以及一切Apple的派生类
ArrayList<? extends Apple> p3 = new ArrayList<Apple>();
p3 = new ArrayList<RedApple>();
// ↓上层的类不接受
// Type mismatch:
// cannot convert from ArrayList<Fruit> to ArrayList<? extends Apple>
// p3 = new ArrayList<Fruit>();
// 【然而,extends是只读的,不能写入】
// p3.add(new Apple());
if (p3.size() != 0) {
Apple apple = p3.get(0);
}
// 【2.<? super Apple>,确定类型继承关系的下界】
// 能装苹果以及一切苹果的基类
ArrayList<? super Apple> p4 = new ArrayList<Apple>();
p4 = new ArrayList<Fruit>();
p4 = new ArrayList<Apple>();
// Type mismatch:
// cannot convert from ArrayList<RedApple> to ArrayList<? super Apple>
// p4 = new ArrayList<RedApple>();
// 【可读可写,读出来的是Object类型】
p4.add(new RedApple());// 子类对象但是可以写进入,因为默认向上转型
Object object = p4.get(0);
System.out.println(object);
// 最后,JDK 7之后,ArrayList后面的<>里什么都不用写
List<Apple> p2 = new ArrayList<>();
}
}
class Fruit {
}
class Apple extends Fruit {
}
class RedApple extends Apple {
}

最新文章

  1. jvm系列(一):java类的加载机制
  2. 微信公众平台API接口
  3. JAVA基础知识之IO——Java IO体系及常用类
  4. 如何同时启动多个Tomcat服务
  5. android 五子棋开发
  6. 进程显示,删除,调度 ps, top kill
  7. js遍历数组和遍历对象的区别
  8. 【转】 iOS开发数据库篇—SQLite简单介绍
  9. C - Coin Change (III)(多重背包 二进制优化)
  10. el和jstl标签库讲解视频
  11. 浅谈线程runnable和callable的使用及区别
  12. linux&amp;php:ubuntu安装php-7.2
  13. QT 用listveiw显示图片
  14. LeetCode 637. Average of Levels in Binary Tree二叉树的层平均值 (C++)
  15. ajax 案例demo
  16. VC++ 删除一个文件目录下的所有文件以及目录
  17. unity profiler - Loading.ReadObject
  18. Interesting JavaScript
  19. 解决dva dispatch yield生成器函数中异常中断,无法继续调用的问题
  20. sql游标使用

热门文章

  1. day79:luffy:注册之对手机号的验证&amp;实现基本的注册功能逻辑&amp;点击获取验证码&amp;redis
  2. PAT Saving James Bond - Easy Version
  3. 【SpringBoot】06.SpringBoot访问静态资源
  4. [阿里DIN] 从模型源码梳理TensorFlow的乘法相关概念
  5. 腾讯云--cdn静态内容上传刷新
  6. php post请求https
  7. Java的图形打印
  8. Javascript的运行效率是原生代码的20%-30%
  9. 利用 Github Actions 的 service container 进行集成测试
  10. 从零开始实现ASP.NET Core MVC的插件式开发(九) - 升级.NET 5及启用预编译视图