java 泛型没有协变类型, 所以要重用extends, 但使用List<? extends Fruit> 可以是ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>(), 因此不能add元素进去
class Fruit{}
class Apple extends Fruit{}
class SubApple extends Apple{}
class Orange extends Fruit{}
class Holder<T>{
private T value;
public Holder(){}
public Holder(T value){this.value = value;}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public boolean equals (Object obj){
return value.equals(obj);
}
}
public class CovarianArrays {
public static void main(String[] args) {
Fruit [] fruitArray = new Apple[10];
fruitArray[0] = new SubApple();
//数组有协变类型,能放入SubApple
//编译时正常。运行时错误 ArrayStoreException 数组在运行时检查类型
//fruitArray[0] = new Fruit();
//fruitArray[1] = new Orange();
//编译时就出错
//List<Fruit> fruitList = new ArrayList<Apple>();
List<Apple> fruitList = new ArrayList<Apple>();
fruitList.add(new Apple());
//只能是Apple,泛型没有协变类型
//fruitList.add(new SubApple());
List<? extends Fruit> fruitExtendList = new ArrayList<Apple>();
//连Object都不行,只能是无意义的null
//fruitExtendList.add(new Apple());
//fruitExtendList.add(new Object());
fruitExtendList.add(null);
List<? extends Fruit> fruitAsList = Arrays.asList(new Apple());
Apple a = (Apple) fruitAsList.get(0);
//以下两个方法的参数都是Object
fruitAsList.contains(new Apple());
int i =fruitAsList.indexOf(new Apple());
System.out.println(i);//-1 不存在
List<? super Apple> supList = new ArrayList<Apple>();
supList.add(new Apple());
supList.add(new SubApple());
//supList.add(new Fruit());
Holder<Apple> holdApple = new Holder<Apple>(new Apple());
Apple a1 = holdApple.getValue();
System.out.println(a1); //com.Array.Apple@10b30a7
//Holder<Fruit> holdFruit = holdApple;
Holder<? extends Fruit> holdFruit = holdApple;
Fruit f1 = holdFruit.getValue();
System.out.println(f1); //com.Array.Apple@10b30a7
Apple a2 = (Apple) holdFruit.getValue();
System.out.println(a2);
Orange o1 = (Orange) holdFruit.getValue(); //运行时出错ClassCastException
System.out.println(o1);
//不能调用setValue()
//holdFruit.setValue(new Orange());
}
}
参考:

java 泛型没有协变类型, 所以要重用extends, 但使用List<? extends Fruit> 可以是ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>(), 因此不能add元素进去的更多相关文章
- Java泛型-内部原理: 类型擦除以及类型擦除带来的问题
一:Java泛型的实现方法:类型擦除 大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除.Java的泛型基本上都是在编译 ...
- java泛型总结(类型擦除、伪泛型、陷阱)
JDK1.5开始实现了对泛型的支持,但是java对泛型支持的底层实现采用的是类型擦除的方式,这是一种伪泛型.这种实现方式虽然可用但有其缺陷. <Thinking in Java>的作者 B ...
- Java泛型的协变
在上篇<Java泛型的基本使用>这篇文章中遗留以下问题,即将子类型也能添加到父类型的泛型中,要实现这种功能必须借助于协变. 实验准备 现在在上篇文章展示的Decorator类型的基础上,增 ...
- Java泛型的协变与逆变
泛型擦除 Java的泛型本质上不是真正的泛型,而是利用了类型擦除(type erasure),比如下面的代码就会出现错误: 报的错误是:both methods have same erasure ...
- JAVA泛型中的类型擦除及为什么不支持泛型数组
一,数组的协变性(covariant array type)及集合的非协变性 设有Circle类和Square类继承自Shape类. 关于数组的协变性,看代码: public static doubl ...
- Java泛型中的类型擦除机制简单理解
Java的泛型是JDK1.5时引入的.下面只是简单的介绍,不做深入的分析. Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...
- 使用Java泛型返回动态类型
返回一个指定类型的集合,并且clazz必须继承IGeoLog对象或者是其本身 <T extends IGeoLog> List<T> getLogListSql(Class&l ...
- Java泛型总结---基本用法,类型限定,通配符,类型擦除
一.基本概念和用法 在Java语言处于还没有出现泛型的版本时,只能通过Object是所有类型的父类和类型强制转换两个特点的配合来实现类型泛化.例如在哈希表的存取中,JDK1.5之前使用HashMap的 ...
- Java泛型的逆变
在上篇<Java泛型的协变>这篇文章中遗留以下问题——协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码清 ...
随机推荐
- 类型化dataset分页
SELECT TOP (@每页行数) 所选列FROM 表名WHERE (主键 NOT IN( SELECT TOP ((@页数-1)*@每页行数) 主键FROM 表名where ( 条件)))AND ...
- WinPE启动U盘的制作方法与软件下载(通用PE工具箱/老毛桃/大白菜WinPE)
转自:http://blog.sina.com.cn/s/blog_58c380370100cp5x.html 文件大小:39.5M(支持Win7安装,早期的通用PE工具箱,小巧不过几十兆,现在都臃肿 ...
- 【MD5加密】MD5加密编码的坑
MD5 MD5即Message-Digest Algorithm (信息-摘要算法5),用于确保信息传输完整一致. 是计算机广泛使用的杂凑算法之一(又译摘要算法.哈希算法),主流编程语言普遍已有MD5 ...
- android基础---->IntentService的使用
这一篇博客,我们开始前台服务与IntentServie源码分析的学习,关于service的生命周期及其简单使用,请参见我的博客:(android基础---->service的生命周期) 目录导航 ...
- LeetCode-394. Decode String(DFS)
Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...
- SharpGL学习笔记(三) 投影变换和视点变换
从本节开始,我们使用SharpGL带的VS2010扩展,来直接生成SharpGL工程. 如果你新建项目时,没有看到下面的SharpGL项目,那么请事先在SharpGL源代码中找到一个叫 ”SharpG ...
- WPS 2019 去除自动升级 和 广告、及优化的点
搜狗输入法 里面的快捷键会影响wps的快捷键功能,需要关掉"搜狗输入法"里面的快捷键 1. 2.去除自动升级功能 3.去除 广告 WPS 2019 流程图(断网): 思维导图: 流 ...
- 跟bWAPP学WEB安全(PHP代码)--SSL(Server-Side-Include)漏洞
什么是Server-Side-Include漏洞 服务端包含漏洞是指发送指令到服务器,服务器会将指令运行完,把运行结果包含在返回文件中发送给你.利用这种漏洞可以获取服务端的信息甚至执行命令,这样的指令 ...
- 熟悉使用ConfigParser库读写配置文件
Python的配置文件 配置文件 setting.ini文件是一个纯文本 [DataBase1] username = admin passwors = root [DataBase2] hostna ...
- 使用DnsCat反弹shell
DnsCat技术特点 Dns隧道反弹shell DnsCat服务器的安装 #git clone https://github.com/iagox86/dnscat2.git #cd dnscat2 # ...