泛型类型
#泛型类型
泛型类型是一个参数化的普通的类或者接口。以下我们通过修改Box类来说明这点。
###一个简单的Box类
我们从一个非泛型的Box类开始。Box类可以操作任何任何类型的对象。它只需要提供两个方法,set用来向Box中增加一个对象和get用来检索这个对象。
既然Box的方法接受或者返回的都是Object。那么你可以传递任何非原生类型的参数。我们在编译时没有办法确定这个类是如何被使用的。一部分代码可能在这个类中放入一个Integer,并且期望取出一个Integer,但是另一部分代码可能错误的将取出的Integer转为String,结果就是出现了运行时异常。
###Box类的泛型版本
一个泛型类可以通过如下的形式定义:
类名后边被尖括号括起来的部分就是类型参数。它声明了类型参数T1,T2…Tn.
为了使Box类使用泛型,我们可以通过改变类声明为“public class Box
经过这些变化,Box类变成了下面这样:
如你所见,所有Object都被替换成了T,一个类型参数可以是任何非原生的类型,包括类,接口,或是数组甚至是其他的类型变量。
和以上相同的技术也可以被用来创建泛型接口。
###类型参数命名习惯
一般来说,类型参数的名字是单个大写字母,这和变量的命名形成了鲜明的对比。这么做的原因是:如果不这样,区分类型变量和普通类的名字将会十分复杂。
最常用类型参数名字如下所示:
- E Element
- K Key
- N number
- T Type
- V value
- S,U,V etc 第二三四…个类型。
这些名字被广泛使用在Java SE API和课程的其他部分中。
###调用和实例化一个泛型类型
想要得到一个Box类的引用,你必须进行泛型类型的调用,在调用中你需要将T替换成一些确定的值如Integer。
你可以将泛型类型调用和普通的参数调用类比,但是不同于提供一个变量给这个方法,你传递了一个类型变量给了Box 类。
类型参数和类型变量:很多开发者将这两个概念互换,然而他们并不相同。Foo
像其他变量声明一样,以上的代码并没有创建一个新的Box对象,他只是声明了integerBox将存放一个‘存放Integer的Box’的引用。这就是Box
一个泛型类型的调用一般被称作参数化类型。
要实例化这个类,使用new关键字。但是我们需要把
TIPS:从java7开始,我们可以这样写了:
###多类型参数
正如之前提及的那样,一个泛型类可以有多个类型参数。举个例子:OrderedPair类,它实现了Pair接口。
以下的代码创建了两个OrderedPair类的实例:
代码new OrderedPair < String, Integer >
将K实例化为String,V实例化为Integer。因此,OrderedPair的构造函数的参数类型为String,和Integer。此外,因为自动装箱技术。我们可以传入int作为参数。
另外根据tips,我们可以写作:
创建泛型接口和创建泛型类的方法相同。
###泛型参数作为参数类型
你也可以将类型参数替换为泛型类。以OrderedPair