1、JavaJava高级程序设计高级程序设计第第4 4章章 JavaJava泛型泛型4.1 应用场景4.2 相关知识4.3 实施过程4.4 拓展知识4.5 拓展训练4.6 课后小结4.7 课后习题4.8 上机实训4.1 应用场景n假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?答案是可以使用 Java 泛型。n使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。n在使用框架SSH(Struts+Spring+Hibernate)开发一个应用系统中,常
2、使用DAO(Date Access Object)来访问数据库对象,完成数据库中的数据和Java对象里的一种关联关系的一系列操作CRUD。数据库中的对象有很多,每一个对象都写一个DAO,显得很繁琐,每一个DAO都要写CRUD操作,这样代码的重复率高,如果使用泛型,代码的复用得到了很好的应用,提高了代码的效率。4.2 相关知识4.2.1 泛型概念4.2.2 泛型的定义4.2.3 相关概念4.2.4 泛型的好处4.2.5 泛型使用时的注意事项4.2.1 泛型概念n所谓“泛型”,就是“宽泛的数据类型”,任意的数据类型。n泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用。使用
3、泛型可以很好的解决“代码复用”问题。4.2.2 泛型的定义n1.定义泛型类n在定义带类型参数的类时,在紧跟类命之后的内,指定一个或多个类型参数的名字,同时也可以对类型参数的取值范围进行限定,多个类型参数之间用,号分隔。n定义完类型参数后,可以在定义位置之后的类的几乎任意地方(静态块,静态属性,静态方法除外)使用类型参数,就像使用普通的类型一样。注意,父类定义的类型参数不能被子类继承。n2.泛型方法n在定义带类型参数的方法时,在紧跟可见范围修饰(例如public)之后的内,指定一个或多个类型参数的名字,同时也可以对类型参数的取值范围进行限定,多个类型参数之间用,号分隔。n定义完类型参数后,可以在
4、定义位置之后的方法的任意地方使用类型参数,就像使用普通的类型一样。例如:4.2.3 相关概念n1.通配符n类型通配符一般是使用?代替具体的类型参数,对类型参数赋予不确定值。例如 List 在逻辑上是List,List 等所有List的父类。n2.上下边界n如果想限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口,也可以是这个类或接口本身。n(1)类型通配符上限通过形如List来定义,如此定义就是通配符泛型值接受Number及其下层子类类型。n(2)类型通配符下限通过形如 List来定义
5、,表示类型只能接受Number及其三层父类类型,如Objec类型的实例。n3.擦除n在使用泛型时没有指明数据类型,为了不出现错误,编译器会将所有数据向上转型为 Object,即擦除泛型类型。n在Java中,泛型是通过类型擦除来实现的,它是Java编译器的概念,Java虚拟机运行时对泛型基本一无所知,理解这一点是很重要的,它有助于我们理解Java泛型的很多局限性。4.2.4 泛型的好处n(1)类型安全。n通过知道使用泛型定义的变量的类型限制,编译器可以更有效地提高Java程序的类型安全。n(2)消除强制类型转换。n消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。所有的强制
6、转换都是自动和隐式的。n(3)提高性能。4.2.5 泛型使用时的注意事项(1)泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。(2)泛型的类型参数可以有多个。4.3 任务实施4.2.1 任务一 泛型类的定义和使用4.2.2 任务二 泛型方法的定义和使用4.2.3 任务三 泛型接口的定义和使用4.3.1 任务一 泛型类的定义和使用n1.定义泛型类n在定义带类型参数的类时,在紧跟类命之后的内,指定一个或多个类型参数的名字,同时也可以对类型参数的取值范围进行限定,多个类型参数之间用,号分隔。n定义完类型参数后,可以在定义位置之后的类的几乎任意地方(静态块,静态属性,静态方法除外)使用类型
7、参数,就像使用普通的类型一样。注意,父类定义的类型参数不能被子类继承。4.3.2 任务二 泛型方法的定义和使用 2.泛型方法在定义带类型参数的方法时,在紧跟可见范围修饰(例如public)之后的内,指定一个或多个类型参数的名字,同时也可以对类型参数的取值范围进行限定,多个类型参数之间用,号分隔。4.3.3 任务三 泛型接口的定义和使用n在定义带类型参数的方法时,在紧跟可见范围修饰(例如public)之后的内,指定一个n3.泛型接口n先定义泛型接口:n然后定义这个实现类来实现这个接口:4.4 拓展知识n在开发高校图书管理系统中,涉及多个数据库中的表,如:图书基本信息表Book,教师信息表Teac
8、her,学生信息表Student,用户表User,出版社信息表Publishing,图书分类信息表Category等。通过DAO(数据访问对象,Date Access Object)实现对数据库中的表进行数据操作,就是数据库中的数据和Java对象里的一种关联关系的一系列操作,包括增删改查(CRUD)操作。n这些基本信息表对应Java的实体类。每个实体类都包含CRUD操作。n这样使得代码冗余度较高。那么能否将这多个DAO相同的方法封装成一个呢?这是可以的,使用泛型类和泛型方法。抽象一个BaseDao,里面封装了实体类相同的操作,当需要操作表的时候,将T换成User或者是Teacher就可以了。4
9、.6 课后小结n1.泛型的本质便是类型参数化,通俗的说就是用一个变量来表示类型,这个类型可以是String,Integer等等不确定,表明可接受的类型。n2.泛型可以接受多个参数,而Object经过强制类型转换可以转换为任何类型,泛型可以把使用Object的错误提前到编译后,而不是运行后,提升安全性。n3.在JAVA的虚拟机中并不存在泛型,泛型只是为了完善java体系,增加程序员编程的便捷性以及安全性而创建的一种机制,在JAVA虚拟机中对应泛型的都是确定的类型,在编写泛型代码后,java虚拟中会把这些泛型参数类型都擦除,用相应的确定类型来代替,代替的这一动作叫做类型擦除,而用于替代的类型称为原
10、始类型,在类型擦除过程中,一般使用第一个限定的类型来替换,若无限定则使用Object。n4.泛型限定是通过?(通配符)来实现的,表示可以接受任意类型。n5.泛型的一些基本规则约束n*泛型的类型参数必须为类的引用,不能用基本类型(int,short,long,byte,float,double,char,boolean)。n*泛型是类型的参数化,在使用时可以用作不同类型(此处在说泛型类时会详细说明)。n*泛型的类型参数可以有多个。4.7 课后习题n三、简答题n1.Java中的泛型是什么?使用泛型的好处是什么?n2.Java的泛型是如何工作的?什么是类型擦除?n3.什么是泛型中的限定通配符和非限定通配符?n4.如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?4.8 上机实训实训一、假如我们现在要定义一个类来表示坐标,要求坐标的数据类型可以是整数、小数和字符串,例如:nx=10、y=10nx=12.88、y=129.65nx=东京180度、y=北纬210度定义泛型类Point,其中定义一个打印坐标的泛型方法printPoint()。并定义一个测试类进行测试,以不同的格式输出给定的坐标值。4.2.2 任务二 泛型方法的定义和使用4.2.2 任务二 泛型方法的定义和使用