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元素进去的更多相关文章

  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. [Linux] 特殊文件 /dev/zero

    /dev/zero 是类 Unix 系统中一个特殊的文件,当读取该文件时,它会提供无限的空字符 null.它的一个主要用途是提供字符流来初始化数据存储,也就是使用空字符覆盖目标数据.另一个常见的用法是 ...

  2. python --->字典 集合 学习笔记

    1.字典--->创建空字典:dict={} broa=["李宁",”耐克“,“阿迪达斯”,“鱼c工作室”] sloga=[“A”,“B”,“C”,“D”] dict={&qu ...

  3. javaweb使用cookie存取中文以及读取中文

    要想在cookie中存储中文,那么必须使用URLEncoder类里面的encode(String s, String enc)方法进行中文转码,例如: 1 Cookie cookie = new Co ...

  4. 发现linux主机再用代理上网的情况下不能用wget从外网下载资源

    公司禁网(也不是完全禁,能连接外网数据库,不能下载东西,不能打开网页,但是却能打开谷歌的收索页面,只是不能点进网页) 发现linux主机再用代理上网的情况下不能用wget从外网下载资源,但是却可以从内 ...

  5. 基于ThinkPHP3.23的简单ajax登陆案例

    本文将给小伙伴们做一个基于ThinkPHP3.2.的简单ajax登陆demo.闲话不多说.直接进入正文吧. 可能有些小伙伴认为TP自带的跳转页面挺好,但是站在网站安全的角度来说,我们不应该让会员看到任 ...

  6. PON系统基础知识简介

    一  PON基础知识 1.1 PON技术概念 PON(Passive Optical Network)即无源光网络,一种基于点到多点(P2MP)拓朴的技术.“无源”指ODN(光分配网络)不含有任何电子 ...

  7. android studio下生成jni头文件

    cd app/src/main javah -d jni -classpath ../../build/intermediates/classes/debug net.sourceforge.lame ...

  8. XCode 遇到的问题

    俗话说:工欲善其事必先利其器.抛弃了VS,投入XCode的怀抱.先不说两者的差距,还是先熟悉开发工具是关键.下面列出个人使用中遇到的一些问题. Problem1:修改Xcode字体颜色以及调整字体大小 ...

  9. LeetCode 20 Valid Parentheses (括号匹配问题)

    题目链接 https://leetcode.com/problems/valid-parentheses/?tab=Description   Problem: 括号匹配问题. 使用栈,先进后出!   ...

  10. 理解proc目录与linux进程、ps命令、netstat命令的关系

    零.proc目录简介 proc目录是虚拟文件系统(VFS)的一种实现,保存了进程信息(pid目录)和一些系统信息. 一.系统的信息 1.cpuinfo和meminfo两个文件 查看CPU和内存相关信息 ...