泛型在Java的集合中广泛应用。为什么我们在Java中需要泛型?了解这个问题可以帮助我们更好地了解很多相关概念。在本文中,我将使用一个非常简短的例子来说明为什么泛型有用。
1. 泛型概述
实现泛型的目的是为了在编译时候而不是运行的时候发现bug。在编译的时候发现和解决bug可以节省时间,因为编译时候的bug更容易发现和解决。泛型只存在于编译时间。这个事实是学习泛型最重要的事情。
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"给它,编译器不知道这是一个问题。当程序运行时候,它会得到一个ClassCastExcpetion。
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而不是Object。如果这样,那么这个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()将返回一个Integer的结果。
4. 总结
总而言之,使用泛型的原因如下:
- 在编译时候强类型检查。
- 消除显示转换。
- 实现更好的代码可重用性,如实现通用算法。
Java的泛型只是一个编译时候概念。在运行的时候,所有的类型信息都被擦除,这是调用类型擦除。这是一个有趣的例子,显示如何避免类型擦除的常见错误。