所谓泛型,就是在定义类、接口、方法、参数或成员变量的时候,指定它们操作对象的类型为通用类型。

使用 尖括号 <> 操作符 (The diamond operator )表示泛型, 尖括号内可以放置大写字母 (代表一个未知类型) 或问号 ? (代表若干个类型)作为参数。比如,习惯上选择以下字母代表某种类型:

  1. T 意味某种类型
  2. E 意味 链表、数组里的元素,如List<E> list 表示 list 里的元素。
  3. K意味map(k,v) 里的键值 Key
  4. V 意味 返回或映射的值。

然而,泛型的运用要受到如下限制 :

  1. 不能使用基本类型的类型参数,可以使用其包装类型代替。
  2. 静态成员无法使用类型参数
  3. 不能使用泛型类异常
  4. 不能实例化泛型对象或数组,如:

T t = new T();  T[] a=new T;

5,. 不能使用泛型数组,如:

import java.util.*;
public class Test{
public static void main(String args[]){
List<String> arr[] = new ArrayList<String>[5];
}
}
D:\java\test\OS_China\generic>javac Test.java
Test.java:5: 错误: 创建泛型数组
List<String> arr[] = new ArrayList<String>[5];
^
1 个错误

至于代表若干类的,放在尖括号内的通配符 ?:<?>,还分 上限通配符 (Upper Bounded Wildcards) 和 下限通配符 (Lower Bounded Wildcards)。

论点:

上限通配符 <?  extends  U> 可以代表这个未知类型 U,或者 通过关键字 extends 所能想象出的 U 类的任何一个子类。同样,下限通配符 <?  super  L> 可以代表这个未知类型 L,或者 通过关键字 super 所能想象出的 L类的任何一个超类。

这里分别以多个接口 interface 和 多个类 class 为基础, 创建 继承关系。

并以通过编译的代码, 证明以上论点成立。

/* <? super T> 与 <? extends T> 的区别,
* T 代表一个给定的接口
* */
import java.util.*;
interface A1{}
interface A2{}
interface A3{}
interface A4{} interface B1 extends A1{}
interface B2 extends A1,A2{}
interface B3 extends A3,A4{}
interface B4 extends A4{} interface C1 extends B2{}
interface C2 extends B2,B3{}
interface C3 extends B3{} interface D1 extends C1,C2{}
interface D2 extends C2{} interface E1 extends D1{}
interface E2 extends D1{}
interface E3 extends D2{}
interface E4 extends D2{} public class UP_Interface { public static void main(String args[]){
/********************************************
* 此处 extends 表示 有上界的统配符 ?,上界为 C2
* 由此定义的引用 listUpper可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
**********************************************/
List<? extends C2> listUpper;//上界统配符 ?, 上界为 C2
listUpper=new ArrayList<C2>();//能存储 C2 D1 D2 E1 E2 E3 E4
listUpper=new ArrayList<D1>();//能存储 D1 E1 E2
listUpper=new ArrayList<D2>();//能存储 D2 E3 E4
listUpper=new ArrayList<E1>();//能存储 E1
listUpper=new ArrayList<E2>();//能存储 E2
listUpper=new ArrayList<E3>();//能存储 E3
listUpper=new ArrayList<E4>();//能存储 E4 /*************************************************
* super 表示有下界的统配符 ? ,下界为 C2 ,
* 由此定义的引用 listLower 可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
***************************************************/
List<? super C2> listLower;
listLower=new ArrayList<A1>(); //能存储 A1 B1 B2 C1 C2 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<A2>(); //能存储 A2 B2 C1 C2 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<A3>(); //能存储 A3 B3 C2 C3 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<A4>(); //能存储 A4 B3 B4 C2 C3 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<B2>(); //能存储 B2 C1 C2 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<B3>(); //能存储 B3 C2 C3 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<C2>();// 能存储 C2 D1 D2 E1 E2 E3 E4
}
}

/* <? super T> 与 <? extends T> 的区别,
* T 代表一个给定的类
* */
import java.util.*; class A1{}
class A2{}
class A3{}
class A4{} class B1 extends A1{}
class B2 extends A1{}
class B3 extends A3{}
class B4 extends A4{} class C1 extends B2{}
class C2 extends B2{}
class C3 extends B3{} class D1 extends C1{}
class D2 extends C2{} class E1 extends D1{}
class E2 extends D1{}
class E3 extends D2{}
class E4 extends D2{} public class UP_Class{ public static void main(String args[]){
/********************************************
* 此处 extends 表示 有上界的统配符 ?,上界为 C2
* 由此定义的引用 listUpper可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
**********************************************/
List<? extends C2> listUpper;//统配符 ? 的上界为 C2
listUpper=new ArrayList<C2>();//能存储 C2 D2 E3 E4
listUpper=new ArrayList<D2>();//能存储 D2 E3 E4
listUpper=new ArrayList<E3>();
listUpper=new ArrayList<E4>();
/*************************************************
* super 表示有下界的统配符 ? ,下界为 C2 ,
* 由此定义的引用 listLower 可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
***************************************************/
List<? super C2> listLower;
listLower=new ArrayList<A1>(); //能存储 A1 B1 B2 C1 C2 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<B2>(); //能存储 B2 C1 C2 D1 D2 E1 E2 E3 E4
listLower=new ArrayList<C2>();// 能存储 D2 E3 E4
}
}

java泛型--问号?和T或E或K或V的区别的更多相关文章

  1. java中?和A、B、T、E、K、V的区别

    使用泛型 List<T> list = new ArrayList<T>(); T t = list.get(0); 不使用泛型 List list = new ArrayLi ...

  2. Java泛型

    什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个 ...

  3. 【Java心得总结四】Java泛型下——万恶的擦除

    一.万恶的擦除 我在自己总结的[Java心得总结三]Java泛型上——初识泛型这篇博文中提到了Java中对泛型擦除的问题,考虑下面代码: import java.util.*; public clas ...

  4. Java泛型总结

    1. 什么是泛型?泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的 ...

  5. java泛型的讲解

    java泛型 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指 ...

  6. Java泛型和通配符那点事

    泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法 ...

  7. java泛型【收藏】

    什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个 ...

  8. Java 泛型 <? super T> 中 super 怎么 理解?与 < ? extends T>有何不同?

    Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同? 简介 前两篇文章介绍了泛型的基本用法.类型擦除以及泛型数组.在泛型的使用中,还有个重要的 ...

  9. Java泛型入门

      Java泛型入门 在学习本章之前,须要对Java的集合(Collection.Map)有一定的基础. Java集合有一个缺点.就是把一个对象"丢进"集合里后,集合就会&qu ...

随机推荐

  1. LB_Yi

    LB_Yi 简述 LB_Yi也是一种比较常见的下界函数,在时间序列的筛选中十分常见.是由Yi在Kim的基础上设计的下界函数. 公式 LB_Yi的公式如下: 从公式中可以明显的看出,其实就是把大于序列最 ...

  2. 使用Restful风格中的post使用过遇到前端数据传送不到后端

    问题描述:使用postman进行请求时候,前端的数据,一直在后端接收不到,找了好多资料,竟然是因为一个注解的原因. 后端接收设置:@RequestParam@ReqeustBody设置的原因 因为sp ...

  3. SVM: 实际中使用SVM的一些问题

    使用SVM包来求θ,选择C与核函数 我们使用已经编写好的软件包(这些软件包效率高,用得多,是经无数人证明已经很好的可以使用的软件包)来求θ,而不是自己去编写软件来求它们(就像我们现在很少编写软件来求x ...

  4. 结构型模式(七) 代理模式(Proxy)

    一.动机(Motivate) 在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者.或者系统结构带来很多麻烦.如何在不 ...

  5. 浏览器兼容问题--get/post

    问题描述: 人员通过发送位置在百度地图上显示出来.删除人员后,chrome地图上该人员也随即消失,但IE浏览器上仍旧存在.清除缓存后,才消失. 原因: IE下面同一个地址,不会多次去请求的.只有加一个 ...

  6. java如何连接数据库并对其操作(以PostgreSQL为例)

    java如何连接数据库并对其操作(以PostgreSQL为例) 相关概念 JDBC(Java Data Base Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数 ...

  7. C# 打开 EXE 文件

    命名空间是using System.Diagnostics; 在编写程序时经常会使用到调用可执行程序的情况,本文将简单介绍C#调用exe的方法.在C#中,通过Process类来进行进程操作. Proc ...

  8. ps -ef、ps aux(查看进程占用内存大小)

    Linux下ps -ef和ps aux的区别及格式详解 Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区别呢?两者没太大差别,讨论这个问题,要追溯到Uni ...

  9. LINQPad 应用

    https://www.linqpad.net/ 使用 LINQPad 调试linq以及lambda表达式 http://www.studyofnet.com/news/1168.html linq ...

  10. learning java Math类

    output: //取整,返回小于目标数的最大整数System.out.println(Math.floor(-1.2));// 取整,返回在于目标数的最大整数System.out.println(M ...