泛型中的extends和super的区别
来源:互联网 发布:开发sql语句美化小工具 编辑:程序博客网 时间:2024/05/17 08:56
在网上看到如下代码,不知道为什么报错,代码如下:
public class GenericTest { public static void main(String[] args) throws Exception { List<? super Fruit> f0=new ArrayList<Fruit>(); f0.add(new Apple()); f0.add(new Fruit()); f0.add(new SupApple()); List<? super Fruit> f1=new ArrayList<Apple>(); f1.add(new Apple()); f1.add(new Fruit()); List<? extends Fruit> f2=new ArrayList<Fruit>(); f2.add(new Apple()); f2.add(new Fruit()); List<? extends Fruit> f3=new ArrayList<Apple>(); f3.add(new Apple()); f3.add(new Fruit()); List<? super Apple> f5=new ArrayList<Fruit>(); f5.add(new Apple()); f5.add(new SupApple()); f5.add(new Fruit()); } } class Fruit{ } class Apple extends Fruit{ } class SupApple extends Apple{ }
首先说下extends和super的却别(参考:点击打开链接):
extends
List<? extends Number> foo3的通配符声明,意味着以下的赋值是合法的:List<?
extends
Number> foo3 =
new
ArrayList<?
extends
Number>();
List<?
extends
Number> foo3 =
new
ArrayList<?
extends
Integer>();
List<?
extends
Number> foo3 =
new
ArrayList<?
extends
Double>();
- 读取操作通过以上给定的赋值语句,你一定能从foo3列表中读取到的元素的类型是什么呢?你可以读取到Number,因为以上的列表要么包含Number元素,要么包含Number的类元素。
你不能保证读取到Integer,因为foo3可能指向的是List<Double>。
你不能保证读取到Double,因为foo3可能指向的是List<Integer>。
- 写入操作过以上给定的赋值语句,你能把一个什么类型的元素合法地插入到foo3中呢?
你不能插入一个Integer元素,因为foo3可能指向List<Double>。
你不能插入一个Double元素,因为foo3可能指向List<Integer>。
你不能插入一个Number元素,因为foo3可能指向List<Integer>。
你不能往List<? extends T>中插入任何类型的对象,因为你不能保证列表实际指向的类型是什么,你并不能保证列表中实际存储什么类型的对象。唯一可以保证的是,你可以从中读取到T或者T的子类。
super
现在考虑一下List<? super T>。List<? super Integer> foo3的通配符声明,意味着以下赋值是合法的:
List<?
super
Integer> foo3 =
new
ArrayList<Integer>();
List<?
super
Integer> foo3 =
new
ArrayList<Number>();
List<?
super
Integer> foo3 =
new
ArrayList<Object>();
- 读取操作通过以上给定的赋值语句,你一定能从foo3列表中读取到的元素的类型是什么呢?你不能保证读取到Integer,因为foo3可能指向List<Number>或者List<Object>。
你不能保证读取到Number,因为foo3可能指向List<Object>。
唯一可以保证的是,你可以读取到Object或者Object子类的对象(你并不知道具体的子类是什么)。
- 写入操作通过以上给定的赋值语句,你能把一个什么类型的元素合法地插入到foo3中呢?你可以插入Integer对象,因为上述声明的列表都支持Integer。
你可以插入Integer的子类的对象,因为Integer的子类同时也是Integer,原因同上。
你不能插入Double对象,因为foo3可能指向ArrayList<Integer>。
你不能插入Number对象,因为foo3可能指向ArrayList<Integer>。
你不能插入Object对象,因为foo3可能指向ArrayList<Integer>。
通过网上查找,最终明白了:
public static void main(String[] args) throws Exception { //定义正确,使用正确。List<? super Fruit> f0 = new ArrayList<Fruit>();f0.add(new Apple());f0.add(new Fruit());f0.add(new SupApple());List<? super Fruit> f1 = new ArrayList<Apple>(); // ArrayList泛型中的只能是Fruit或者Object,即Fruit本身或者Fruit的父类类型。f1.add(new Apple());f1.add(new Fruit());//定义正确,使用错误。List<? extends Fruit> f2 = new ArrayList<Fruit>();//添加了Apple,f2有可能指向ArrayList<SupApple>f2.add(new Apple());//添加了Fruit,f2有可能指向ArrayList<SupApple>/ArrayList<Apple>f2.add(new Fruit());//定义正确,使用错误。List<? extends Fruit> f3 = new ArrayList<Apple>();//添加了Apple,f3有可能指向ArrayList<SupApple>f3.add(new Apple());//添加了Apple,f3有可能指向ArrayList<SupApple>/ArrayList<Apple>f3.add(new Fruit());//只能添加Apple以及Apple的子类List<? super Apple> f5 = new ArrayList<Fruit>();f5.add(new Apple());f5.add(new SupApple());f5.add(new Fruit());/** * 总结: * extends,只能读取,不能写。 * super:可以读取,且只能返回Object类型,或Object的子类对象(但是不能确定具体的子类是什么) * 可以写,? super Xxx ,只能写Xxx或Xxx的子类对象。 */ }
- 泛型中的extends和super的区别
- Java 范型中的super和extends的区别
- 浅谈Java泛型中的<? extends E>和<? super E>的区别
- java泛型中的extends和super
- java泛型中的extends和super
- JAVA 泛型中的extends和super
- java generic super/extends (java 泛型中的super/extends)
- java泛型中extends 和 super的区别
- <? super T>和<? extends T>的区别
- 浅谈Java泛型中的extends和super关键字
- 浅谈Java泛型中的extends和super关键字
- 浅谈Java泛型中的extends和super关键字
- 浅谈Java泛型中的extends和super关键字
- 浅谈Java泛型中的extends和super关键字
- 浅谈Java泛型之<? extends T>和<? super T>的区别
- java泛型中的extends super再解
- JAVA泛型的? extends和? super的比较
- JAVA泛型通配符 extends 和 super
- Java并发(二)——Lock
- docker 命令简介
- Android查看当前应用通知开启状态
- Integer.valueOf(String) 方法之惑
- 五大常用算法(五)分支限界法
- 泛型中的extends和super的区别
- Elasticsearch 字段数据类型
- 575
- 基于vue、vuex、vue-router、echarts搭建的数据展示平台
- 设计模式之迭代器模式
- 汇编程序:批量复制并显示字符
- java程序员开发参考资源
- 通过Spring Data Neo4J操作您的图形数据库
- 公司服务器被攻击,tomcat不停的响应,日志不停的刷,iptables配置后解决