再论<? extends T>和<? super T>
2024-10-18 19:56:49
参考:
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 {
}
最新文章
- jvm系列(一):java类的加载机制
- 微信公众平台API接口
- JAVA基础知识之IO——Java IO体系及常用类
- 如何同时启动多个Tomcat服务
- android 五子棋开发
- 进程显示,删除,调度 ps, top kill
- js遍历数组和遍历对象的区别
- 【转】 iOS开发数据库篇—SQLite简单介绍
- C - Coin Change (III)(多重背包 二进制优化)
- el和jstl标签库讲解视频
- 浅谈线程runnable和callable的使用及区别
- linux&;php:ubuntu安装php-7.2
- QT 用listveiw显示图片
- LeetCode 637. Average of Levels in Binary Tree二叉树的层平均值 (C++)
- ajax 案例demo
- VC++ 删除一个文件目录下的所有文件以及目录
- unity profiler - Loading.ReadObject
- Interesting JavaScript
- 解决dva dispatch yield生成器函数中异常中断,无法继续调用的问题
- sql游标使用
热门文章
- day79:luffy:注册之对手机号的验证&;实现基本的注册功能逻辑&;点击获取验证码&;redis
- PAT Saving James Bond - Easy Version
- 【SpringBoot】06.SpringBoot访问静态资源
- [阿里DIN] 从模型源码梳理TensorFlow的乘法相关概念
- 腾讯云--cdn静态内容上传刷新
- php post请求https
- Java的图形打印
- Javascript的运行效率是原生代码的20%-30%
- 利用 Github Actions 的 service container 进行集成测试
- 从零开始实现ASP.NET Core MVC的插件式开发(九) - 升级.NET 5及启用预编译视图