13.1 为什么要使用泛型程序设计
泛型程序设计(generic programming)意味着编写的代码可以被很多不同类型的对象所重用。
类型参数的魅力在于,使得程序具有更好的可读性和安全性。
1.3.2 简单泛型类的定义
一个泛型类(generic class)就是具有一个或多个类型变量的类。
注意:类型变量使用大写形式,且比较短,这是很常见的。在Java库中,使用变量E表示集合的元素类型,K和V分别表示表的关键字与值的类型。T(需要时还可以用临近的字母U和S)表示“任意类型”。
泛型类可以看作普通类的工厂。
13.3 泛型方法
class ArrayAlg
{
public static <T>T getMiddle(T[] a)
{
return a[a.length/2]
}
}
注意,类型变量放在修饰符(这里是public static)的后面,返回类型的前面。
定义泛型的方法可以在普通类中,也可以在泛型类中。
当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型:
String[] names={"John","Q","Public"};
String middle=ArrayAly.<String>getMiddle(names);
在这种情况下(实际也是大多数情况)下,方法调用中可以省略<String>类型参数。编译器有足够的信息判断所要的方法。它用names的类型(即String[])与泛型类型T[]进行匹配并判断出T一定是String。也就是说,可以调用
String middle=ArrayAlg.getMiddle(names);
13.4 类型变量的限定
可以通过对类型变量T设置限定(bound)来做到这一点:
public static<T extends Comparable>T min(T[] a)...
一个类型变量或通配符可以有多个限定,例如
T extends Comparable&Serializable
限定类型用“&”分隔,这是因为头号用来分隔类型变量。
在Java的继承中,可以根据需要拥有多个接口超类型,但界限中至多有一个类。如果用一个类作为界限,它必须是界限列表中的第一个。
13.5 泛型代码和虚拟机
虚拟机没有泛型类型对象——所有对象都属于普通类。
如果使用Sun的编译器来编译使用Java泛型的代码,结果类文件将不能在5.0之前的虚拟机上运行。
无论何时定义一个泛型类型,相应的原始类型(raw type)都会被自动地提供。原始类型的名字就是删去了类型参数的泛型类型的名字。类型变量被擦除(erased),并用其限定类型(无限定的变量用Object)替换。
注意:读者可能想要知道切换限定:class Intercal<Serializable&Comparable>会发生什么。如果是这样的话,原始类型用Serializable替换T,而编辑器在必要时要向Comparable插入强制类型转换。为了提高效率,应该将标签(tagging)接口(即没有方法的接口)放在边界列表的末尾。
13.5.1 翻译泛型表达式
13.5.2 翻译泛型方法
总之,要记住有关Java泛型转换的事实:
1)虚拟机中没有泛型,只有普通的类和方法。
2)所有的类型参数都用它们的边界替换。
3)桥方法被合成为保持多态的。
4)为保持类型安全性,必要时插入强制类型转换。
13.5.3 调用遗留代码
13.6 约束与局限性
13.6.1 基本类型
不能用类型参数替换基本类型。因此,没有Pair<double>,只有Pair<Double>。
13.6.2 运行时类型查询
虚拟机中的对象总有一个特定的非泛型类型。因此,所有的类型查询只产生原始类型。
13.6.3 异常
不能抛出也不能捕获泛型类的对象。事实上,泛型类扩展Throwable都不合法。
不能再catch自己种使用类型变量。但是,在异常声明中可以使用类型变量。
13.6.4 数组
不能声明参数化类型的数组。
提示:如果需要收集参数化类型对象,直接使用ArrayList:ArrayList<Pair<String>>最安全且有效
13.6.5 泛型类型的实例化
不能实例化泛型类型。类似地,不能建立一个泛型数组:
public <T> T[] minMax(T[] a){T[] mm=new T[2];...}
类型擦除会让这个方法总是构造一个Object[2]数组。
但是,通过调用Class.newInstance和Array.newInstance方法,可以利用反射构造泛型对象和数组。
13.6.6 静态上下文
不能再静态域或方法中引用类型变量。
13.6.7 擦除后的冲突
当泛型类型被擦除时,创建条件不能产生冲突。
泛型规范说明提及另一个原则:“要支持擦除的转换,需要强行限制一个类或类型变量不能同时成为两个接口类型的子类,而这两个接口是同一接口的不同参数化。”
13.7 泛型类型的继承规则
无论S与T有什么联系,通常,Pair<S>都和Pair<T>没有什么联系。
最后,泛型类可以扩展或实现其他的泛型类。就这一点而言,与普通的类没有什么区别。
13.8 通配符类型
通配符类型:
Pair<? extends Employee>
表示任何的泛型Pair类型,它的类型参数是Employee的子类,如Pair<Manager>;
13.8.1 通配符的超类型限定
通配符限定与类型变量限定十分类似,但是,它还有一个附加的能力,即可以指定一个超类型限定(supertype bound),如下所示:
? super Manager
这个通配符限制为Manager的所有超类型。
直观地讲,带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。
13.8.2 无限定通配符
13.8.3 通配符捕获
通配符不是类型变量,因此,不能再编写代码中使用"?"作为一种类型。
通配符捕获只有在许多限制的情况下才是合法的。编译器必须能够确信通配符表达的是单个、确定的类型。
13.9 反射和泛型
13.9.1 使用Class<T>参数进行类型匹配
13.9.2 虚拟机中的泛型类型信息
Java泛型的卓越特性之一是在虚拟机中的泛型类型的擦除。令人感到奇怪的是,擦除的类仍然保留一些它们泛型祖先的微弱记忆。
注意:包含在类文件中的似的泛型反射可用的类型信息同旧的虚拟机不兼容。
为了表达泛型类型声明,JDK5.0在Java.lang.reflect包中提供了一个新的接口Type。该接口有如下子类型:
1)Class类,描述具体类型。
2)TypeVariable接口,描述类型变量(如T extends Comparable<? super T>)
3)WildcardType接口,描述通配符(如 ? super T )
4)ParameterizedType接口,描述泛型类或接口类型(如Comparable<? super T>)
5)GenericArrayType接口,描述泛型数组(如 T[])
分享到:
相关推荐
本资源提供了 Java 语言程序设计基础篇第十三章的练习标准答案,涵盖了面向对象编程、集合框架、泛型、方法重写和数组操作等多个知识点。这将有助于读者更好地理解 Java 语言的基本概念和编程技术。
继承与派生 第8章 多态性 第9章 群体类和群体数据的组织 第10章 泛型程序设计与C++标准模板库 第11章 流类库与输入/输出 第12章 异常处理 第13章 MFC库与WINDOWS程序开发概述
这是一个txt文件,迅雷下载地址,复制,新建,下载就可以了 第1章 Java 程序设计概述 第2章 Java程序设计环境 第3章 Java基本的程序设计程序 第4章 对象与类 ...第12章 泛型程序设计 第13章 集合 第14章 多线程
第1章 Java 程序设计概述 1.1 Java 程序设计平台 1.2 Java 白皮书的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 1.2.4 健壮性 1.2.5 安全性 ...第12章 泛型程序设计 第13章 集合 第14章 多线程
第1章 Java 程序设计概述 1.1 Java 程序设计平台 1.2 Java 白皮书的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 1.2.4 健壮性 1.2.5 安全性 ...第12章 泛型程序设计 第13章 集合 第14章 多线程
共分为两个压缩包 此为第2个压缩包 第1章 Java 程序设计概述 1.1 Java 程序设计平台 1.2 Java 白皮书的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 ...第12章 泛型程序设计 第13章 集合 第14章 多线程
共分两个压缩包 此为第一个压缩包 第1章 Java 程序设计概述 1.1 Java 程序设计平台 1.2 Java 白皮书的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 ...第12章 泛型程序设计 第13章 集合 第14章 多线程
《C 程序设计语言》(原书第4版)是C 领域最经典的参考书,介绍了C 11的...第24章 泛型程序设计 595 第25章 特例化 613 第26章 实例化 629 第27章 模板和类层次 645 第28章 元编程 661 第29章 一个矩阵设计 701
第13章 容器和泛型.pptx 第14章 流与文件(1).pptx 第14章 流与文件(2).pptx 第15章 网络编程.pptx 第1章 Java概述.pptx 第2章 Java基础.pptx 第3章 数组.pptx 第4章 类和对象(1).pptx 第4章 类和对象(2)....
《JAVA核心技术 中文第八版》共分(卷1基础知识)和(卷2高级特性)两部分,由于文件比较大,共拆分为7个分卷: (卷1拆分为4个分卷,卷2拆分为3个分卷) ...第12章 泛型程序设计 第13章 集合 第14章 多线程
《JAVA核心技术 中文第八版》共分(卷1基础知识)和(卷2高级特性)两部分,由于文件比较大,共拆分为4个分卷: (由于上传权限原因,卷1拆分为2个分卷,卷2拆分为2...第12章 泛型程序设计 第13章 集合 第14章 多线程
《JAVA核心技术 中文第八版》共分(卷1基础知识)和(卷2高级特性)两部分,由于文件比较大,共拆分为4个分卷: (由于上传权限原因,卷1拆分为2个分卷,卷2拆分为2...第12章 泛型程序设计 第13章 集合 第14章 多线程
第13章图形界面设计(第7版).pptx 第14章事件处理(第7版).pptx 第15章绘图与动画程序设计(第7版).pptx 第16章 多线程(第7版).pptx 第17章网络程序设计(第7版).pptx 第18章 Java数据库程序设计(第7版).pptx
Visual C# 2010程序设计...第13章 文件与注册表编程 目录操作 文件管理 读写文件 第14章 语言集成查询-LINQ LINQ实现基础 LINQ概述 LINQ和泛型 LINQ查询步骤 LINQ查询语句 LINQ和数据库操作
第13章图形界面设计(第7版)相关案例代 第14章事件处理(第7版)相关案例代 第15章绘图与动画程序设计(第7版)相关案例代 第16章 多线程(第7版)相关案例代 第17章网络程序设计(第7版)相关案例代 第18章 Java数据库程序...
梁勇编著的《Java语言程序设计》第十版是一本广泛使用的教材,旨在帮助读者深入理解Java编程。这本书不仅涵盖了Java的基础知识,还包含了面向对象编程的核心理念和实践技巧。 在提供的压缩包"java语言程序设计 梁勇...
共分14章,主要内容包括.NET平台与Visual Studio 2010开发环境、C#语言基础及面向对象程序设计、C#程序设计、C# Web程序设计、C#泛型编程、C#数据库程序设计及ADO.NET等相关知识,并在最后讲解了运用C#处理文件和...
更新到jdk 6平台,但和 第七版没有本质的区别 ... 1 AN INTRODUCTION TO JAVA Java As a Programming Platform The Java “White Paper” Buzzwords ...第12章 泛型程序设计 第13章 集合 第14章 多线程