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. es5.0 安装head插件

    es5.0的安装和之前的版本有些区别,我的电脑用plugin install 没成功, 查了一下资料,说是可以用grunt进行安装,启动; 1,先安装grunt: grunt是一个很方便的构建工具,可 ...

  2. Mac下Intellij IDea发布JavaWeb项目 详解三 (为所有Module配置Tomcat Deployment 并测试web 网页 配置Servlet)

    step4 为所有项目配置Deployment 4.1 如图 4.2 [+][Artifact] 4.3 将这里列出的所有内容选中后,点[OK] 4.4 选完是这样,表示,这三个java ee 项目会 ...

  3. VC利用调试寄存器实现硬件断点源码

    [文章标题]:VC利用调试寄存器实现硬件断点源码 [文章作者]:yhswwr(SilenceRet) [作者QQ]:3412259 [编写语言]:C++ [使用工具]:VS2008.VC++9 [本文 ...

  4. ldap 测试表设计

    1. ldap_oc_mappings    存储objeckClass 信息 表结构:  Column Desc. id objectClass的唯一标识 name objectClass的名称 k ...

  5. .net环境下的缓存技术-转载!

    摘要: 介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页) 1         概念 1.1   缓存能解决的问题 · 性 ...

  6. vuex - 简单使用步骤梳理,轻松掌握、附源码

    -----------------------往期----------------------------- vuex - 学习日记 vuex - 辅助函数学习 vuex - 常用命令学习及用法整理 ...

  7. LeetCode 80 Remove Duplicates from Sorted Array II(移除数组中出现两次以上的元素)

    题目链接:https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/#/description 给定一个已经排好序的数组 ...

  8. hihoCoder挑战赛28 题目1 : 异或排序

    题目1 : 异或排序 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个长度为 n 的非负整数序列 a[1..n] 你需要求有多少个非负整数 S 满足以下两个条件: ...

  9. Jdk提供的动态代理示例

    package com.jiaoyiping.util.demo; import java.lang.reflect.InvocationHandler; import java.lang.refle ...

  10. 如何查看当前项目Laya的引擎版本

    打开项目后在调试控制台输入 Laya.version