1. class Fruit{}
  2. class Apple extends Fruit{}
  3. class SubApple extends Apple{}
  4. class Orange extends Fruit{}
  5.  
  6. class Holder<T>{
  7. private T value;
  8. public Holder(){}
  9. public Holder(T value){this.value = value;}
  10. public T getValue() {
  11. return value;
  12. }
  13. public void setValue(T value) {
  14. this.value = value;
  15. }
  16. public boolean equals (Object obj){
  17. return value.equals(obj);
  18. }
  19.  
  20. }
  21. public class CovarianArrays {
  22.  
  23. public static void main(String[] args) {
  24. Fruit [] fruitArray = new Apple[10];
  25. fruitArray[0] = new SubApple();
  26. //数组有协变类型,能放入SubApple
  27. //编译时正常。运行时错误 ArrayStoreException 数组在运行时检查类型
  28. //fruitArray[0] = new Fruit();
  29. //fruitArray[1] = new Orange();
  30.  
  31. //编译时就出错
  32. //List<Fruit> fruitList = new ArrayList<Apple>();
  33.  
  34. List<Apple> fruitList = new ArrayList<Apple>();
  35. fruitList.add(new Apple());
  36. //只能是Apple,泛型没有协变类型
  37. //fruitList.add(new SubApple());
  38.  
  39. List<? extends Fruit> fruitExtendList = new ArrayList<Apple>();
  40. //连Object都不行,只能是无意义的null
  41. //fruitExtendList.add(new Apple());
  42. //fruitExtendList.add(new Object());
  43. fruitExtendList.add(null);
  44.  
  45. List<? extends Fruit> fruitAsList = Arrays.asList(new Apple());
  46. Apple a = (Apple) fruitAsList.get(0);
  47. //以下两个方法的参数都是Object
  48. fruitAsList.contains(new Apple());
  49. int i =fruitAsList.indexOf(new Apple());
  50. System.out.println(i);//-1 不存在
  51.  
  52. List<? super Apple> supList = new ArrayList<Apple>();
  53. supList.add(new Apple());
  54. supList.add(new SubApple());
  55. //supList.add(new Fruit());
  56.  
  57. Holder<Apple> holdApple = new Holder<Apple>(new Apple());
  58. Apple a1 = holdApple.getValue();
  59. System.out.println(a1); //com.Array.Apple@10b30a7
  60.  
  61. //Holder<Fruit> holdFruit = holdApple;
  62. Holder<? extends Fruit> holdFruit = holdApple;
  63. Fruit f1 = holdFruit.getValue();
  64. System.out.println(f1); //com.Array.Apple@10b30a7
  65. Apple a2 = (Apple) holdFruit.getValue();
  66. System.out.println(a2);
  67. Orange o1 = (Orange) holdFruit.getValue(); //运行时出错ClassCastException
  68. System.out.println(o1);
  69. //不能调用setValue()
  70. //holdFruit.setValue(new Orange());
  71.  
  72. }
  73.  
  74. }

参考:

java 泛型没有协变类型, 所以要重用extends, 但使用List<? extends Fruit> 可以是ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>(), 因此不能add元素进去的更多相关文章

  1. Java泛型-内部原理: 类型擦除以及类型擦除带来的问题

    一:Java泛型的实现方法:类型擦除 大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除.Java的泛型基本上都是在编译 ...

  2. java泛型总结(类型擦除、伪泛型、陷阱)

    JDK1.5开始实现了对泛型的支持,但是java对泛型支持的底层实现采用的是类型擦除的方式,这是一种伪泛型.这种实现方式虽然可用但有其缺陷. <Thinking in Java>的作者 B ...

  3. Java泛型的协变

    在上篇<Java泛型的基本使用>这篇文章中遗留以下问题,即将子类型也能添加到父类型的泛型中,要实现这种功能必须借助于协变. 实验准备 现在在上篇文章展示的Decorator类型的基础上,增 ...

  4. Java泛型的协变与逆变

    泛型擦除 Java的泛型本质上不是真正的泛型,而是利用了类型擦除(type erasure),比如下面的代码就会出现错误: 报的错误是:both methods  have same erasure ...

  5. JAVA泛型中的类型擦除及为什么不支持泛型数组

    一,数组的协变性(covariant array type)及集合的非协变性 设有Circle类和Square类继承自Shape类. 关于数组的协变性,看代码: public static doubl ...

  6. Java泛型中的类型擦除机制简单理解

    Java的泛型是JDK1.5时引入的.下面只是简单的介绍,不做深入的分析. Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...

  7. 使用Java泛型返回动态类型

    返回一个指定类型的集合,并且clazz必须继承IGeoLog对象或者是其本身 <T extends IGeoLog> List<T> getLogListSql(Class&l ...

  8. Java泛型总结---基本用法,类型限定,通配符,类型擦除

    一.基本概念和用法 在Java语言处于还没有出现泛型的版本时,只能通过Object是所有类型的父类和类型强制转换两个特点的配合来实现类型泛化.例如在哈希表的存取中,JDK1.5之前使用HashMap的 ...

  9. Java泛型的逆变

    在上篇<Java泛型的协变>这篇文章中遗留以下问题——协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码清 ...

随机推荐

  1. C++ template —— 深入模板基础(二)

    上一篇C++ template —— 模板基础(一)讲解了有关C++模板的大多数概念,日常C++程序设计中所遇到的很多问题,都可以从这部分教程得到解答.本篇中我们深入语言特性.------------ ...

  2. .vimrc设置说明

    在终端下使用vim进行编辑时,默认情况下, 编辑的界面上是没有显示行号.语法高亮度显示.智能缩进等功能的. 为了更好的在vim下进行工作,需要手动设置一个配置文件:.vimrc. 在启动vim时,当前 ...

  3. 【Spring源码分析系列】启动component-scan类扫描加载过程

    原文地址:http://blog.csdn.net/xieyuooo/article/details/9089441/ 在spring 3.0以上大家都一般会配置一个Servelet,如下所示: &l ...

  4. 【CSS系列】获取实时数据做进度

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Android ADB命令?这一次我再也不死记了!【简单说】

    https://www.jianshu.com/p/56fd03f1aaae adb的全称为Android Debug Bridge.是android司机经常用到的工具.但是问题是那么多命令写代码已经 ...

  6. java(8) HashMap源码

    系统环境: JDK1.7 HashMap的基本结构:数组 + 链表.主数组不存储实际的数据,存储的是链表首地址. 成员变量 //默认数组的初始化大小为16 static final int DEFAU ...

  7. git 推送出现 "fatal: The remote end hung up unexpectedly"

    原因:原因是推送的文件太大 解决方案: 注意,有时候会看不到.git文件,可能被隐藏了,在这里勾选上隐藏的项目,就可以看到了. 第一种,全局设置 在C:\Users\wang\git\.git\con ...

  8. openstack-networking-neutron(二)---tun/tap

    本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. 简介 虚拟网卡Tun/tap驱动是一个开源项目,支持很多的类UNIX平台,Ope ...

  9. CentOS6.4挂载读写NTFS分区 (重要)

    如今很多的linux衍生版本已经支持自动连接NTFS分区了,之前在一次安装的过程中,遇到 linux不能识别NTFS分区,解决方法如下文: ============================== ...

  10. Metrics.Net构建指标监控中心

    Metrics.NET(https://github.com/etishor/Metrics.NET)是一个给CLR 提供度量工具的包,它是移植自Java的metrics,支持的平台 .NET 4.5 ...