正文
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
Java语言引入泛型的好处是安全简单。
泛型什么样子
Class ArrayList<E>:声明一个泛型类ArrayList,其中E可以使用任意一个具体类型替代,泛型类型往往使用一个大写字母表示。
public boolean add(E o):E是泛型,也就是说,使用add方法时,可以为其传递任意一种类型的参数。其中此处的E是在类中定义的
Java中泛型的作用:简单安全
在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的值保存在集合中
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型可提高代码的高扩展性和重用率
.
1
、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2
、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同
版本的泛型类实例是不兼容的。
3
、泛型的类型参数可以有多个。
4
、泛型的参数类型可以使用
extends
语句,例如
<T extends
superclass>
。习惯上称为“有界类型”。
5
、
泛型的参数类型还可以是通配符类型。
例如
Class<?> classType =
Class.forName("java.lang.String");
泛型可以用在接口,类方法,集合上面
.
泛型接口:
interface testGenerics<T>{
T getT(T t);
String assume(T t);
}
泛型类:
public class GenericsFoo<T> {
private T x;
public GenericsFoo(T x) {
this.x = x;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
}
使用
<T>
来声明一个类型持有者名称,
然后就可以把
T
当作一个类型代
表来声明成员、参数和返回值类型。
当然
T
仅仅是个名字,这个名字可以自行定义。
泛型方法:
是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方
法,只需将泛型参数列表置于返回值前。如
:
public class ExampleA {
public <T> void f(T x) {
System.out.println(x.getClass().getName());
}
使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。
泛型方法除了定义不同,调用就像普通方法一样。
限制泛型的可用类型:
在上面的例子中,由于没有限制
class GenericsFoo<T>
类型持有
者
T
的范围,实际上这里的限定类型相当于
Object
,这和“
Object
泛
型”实质是一样的。限制比如我们要限制
T
为集合接口类型。只需要这
么做:
class GenericsFoo<T extends Collection>
,这样类中的泛型
T
只能是
Collection
接口的实现类,
传入非
Collection
接口编译会出错。
注意:
<T extends Collection>
这里的限定使用关键字
extends
,
后面可以是类也可以是接口。但这里的
extends
已经不是继承的含义
了,应该理解为
T
类型是实现
Collection
接口的类型,或者
T
是继承
了
XX
类的类型。
下面继续对上面的例子改进,我只要实现了集合接口的类型:
public class CollectionGenFoo<T extends Collection> {
private T x;
public CollectionGenFoo(T x) {
this.x = x;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
}
通配符泛型:
为了解决类型被限制死了不能动态根据实例来确定的缺点,引入了