为什么需要泛型类型(Generic types)?
原文地址:http://www.programcreek.com/2012/04/why-do-we-need-generic-types-in-java/
泛型类型在 Java 集合中被广泛使用。 为什么我们需要 Java 中 的泛型类型呢?了解泛型类型可以帮助我们更好地了解很多其他相关的问题。 在本文中,我将使用一个很简单的例子来说明为什么泛型是很有用的。
1. 概述
实现泛型的目的是在编译时发现错误,而不是在运行时。 在编译时查找错误可以节省调试 Java 程序的时间,因为编译时的错误更容易找到和修复。 泛型类型只存在于编译时,这是学习 Java 泛型最重要的事情。
2. 假如没有泛型?
在以下程序中,"Room" 类定义了一个成员对象,我们可以传递任何对象,如 String,Integer 等。
class Room {
private Object object;
public void add(Object object) {
this.object = object;
}
public Object get() {
return object;
}
}
public class Main {
public static void main(String[] args) {
Room room = new Room();
room.add(60);
//room.add("60"); //this will cause a run-time error
Integer i = (Integer)room.get();
System.out.println(i);
}
}
当我们添加一个整数并进行转换时,程序运行得很好。 但是如果一个用户意外地添加一个字符串 “60” 进去,编译器不知道这是一个问题,程序运行时会得到 ClassCastException 异常。
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at collection.Main.main(Main.java:21)
您可能会问,为什么不将字段类型声明为 Integer?如果这样,那么 "Room" 类功能就很单一了,因为它只能存储一种类型的东西。
3. 使用泛型
使用泛型修改上面的代码:
class Room<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
public class Main {
public static void main(String[] args) {
Room<Integer> room = new Room<Integer>();
room.add(60);
Integer i = room.get();
System.out.println(i);
}
}
现在如果有人添加 room.add("60"),编译时将提示错误:

以上代码,可以很容易地看到它是如何工作的,另外,也没有必要从 room.get() 转换结果,因为编译知道 get() 将返回一个整数。
4. 总结
使用泛型的原因:
- 编译时严格的类型检查
- 消除类型的显示转换
- 提高代码重用性,如实现通用算法
Java 泛型类型只是一个编译时的概念。在运行期间,所有类型的信息都会被删除,这就是类型擦除。 这是一个有趣的 示例,讲的是如何避免类型擦除中的常见错误,有兴趣的可以看一下。
参考阅读: