参考文章:
http://www.cnblogs.com/lwbqqyumidi/p/3837629.html
http://blog.csdn.net/caihuangshi/article/details/51278793
http://www.cnblogs.com/lucky_dai/p/5589317.html
泛型的概念及好处
泛型,也称为“参数化类型”,可以简单的理解为将类型也作为一个变量参数,在使用/调用时传入具体的类型。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。在未引入泛型之前,都是通过对类型Object的引用来实现参数的“任意化”,这样的话会带来两个问题:
- 当使用这个对象的时候,每一次都需要强制转换为需要的类型
- 对于强制转换类型的错误,编译器不会产生任何错误提示
而泛型的好处就是在编译的时候会检查类型安全,所有的强制转换都是自动和隐式的,提高代码的重用率。 可以来看下面一个对比例子:
public class GenericTest {
public static void main(String[] args) {
List list = new ArrayList();
list.add("qqyumidi");
list.add("corn");
list.add(100);
for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i); // 编译不会报错,运行到这里会报错
System.out.println("name:" + name);
}
}
}
在例子中,定义了一个List类型集合,其默认类型为Object类型,所以在加入String类型后不小心加入了Integer类型,在编译阶段编译类型还是Object,强制转换并不会报“java.lang.ClassCastException”异常,而在运行时运行类型就变为Integer本身,然后就会报错了。
再看使用泛型以后:
public class GenericTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("qqyumidi");
list.add("corn");
//list.add(100); // 提示编译错误
for (int i = 0; i < list.size(); i++) {
String name = list.get(i); // 自动转换
System.out.println("name:" + name);
}
}
}
在使用泛型以后,在添加Integer类型对象就会出现编译错误。因为通过List
泛型类
泛型类就是具有一个或多个类型参数的类,如下实例代码:
public class Pair<T, U> {
private T first;
private U second;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public U getSecond() {
return second;
}
public void setFirst(T newValue) {
first = newValue;
}
public void setSecond(U newValue) {
second = newValue;
}
}
泛型类Pair的类型参数为T、U,放在类名后的尖括号中。这里的T即Type的首字母,代表类型的意思,常用的还有E(element)、K(key)、V(value)等。当然不用这些字母指代类型参数也完全可以。 实例化泛型类的时候,我们只需要把类型参数换成具体的类型即可,比如实例化一个Pair<T, U>类我们可以这样:
Pair<String, Integer> pair = new Pair<String, Integer>();
泛型方法
所谓泛型方法,就是带有类型参数的方法,它既可以定义在泛型类中,也可以定义在普通类中。
类型变量的限定
在有些情况下,泛型类或者泛型方法想要对自己的类型参数进一步加一些限制。比如,我们想要限定类型参数只能为某个类的子类或者只能为实现了某个接口的类。相关的语法如下: