什么是泛型?
泛型其实就是将一个集合或者一个容器指定了入参的数据类型,或者说可以将类型当作参数传递给一个类或方法。
而使用泛型又带来了那些好处,首先看以下代码:
public class Cache {
Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
Cache cache = new Cache();
cache.setValue(134);
int value = (int) cache.getValue();
cache.setValue("hello");
String value1 = (String) cache.getValue();
通过以上代码,我们可以看出Cache类中我们可以存取任意类型的值,这样使用起来也简单,只不过在取值时做强制转换罢了
但是我们在使用泛型后,就会为我们带来不一样的感受
public class Cache<T> {
T value;
public Object getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
Cache<String> cache1 = new Cache<String>();
cache1.setValue("123");
String value2 = cache1.getValue();
Cache<Integer> cache2 = new Cache<Integer>();
cache2.setValue(456);
int value3 = cache2.getValue();
从以上代码我们可以看出,使用泛型后显而易见的就是我们取值时不需要进行强制转换了,使用泛型后除了解决了强制转换还带了一个好处就是规定了数据入参的类型,在编译器中就可以明显看出
所以使用泛型主要为我们带来了以下几个好处
1、类型的安全。
2、消除强制类型转换。
3、潜在性能的收益。
类型擦除
泛型是java1.5引进的概念,泛型信息只存在于代码编译阶段,在进入JVM之前会将泛型的信息擦除掉,专业术语叫“类型擦除”。
Erasure<String> erasure = new Erasure<String>("hello");
Class eclz = erasure.getClass();
System.out.println("erasure class is:"+eclz.getName());
打印结果
erasure class is:com.frank.test.Erasure
Class 的类型仍然是 Erasure 并不是 Erasure这种形式,那我们再看看泛型类中 T 的类型在 jvm 中是什么具体类型。
Field[] fs = eclz.getDeclaredFields();
for ( Field f:fs) {
System.out.println("Field name "+f.getName()+" type:"+f.getType().getName());
}
打印结果
Field name object type:java.lang.Object
那我们可不可以说,泛型类被类型擦除后,相应的类型就被替换成 Object 类型呢?
这种说法,不完全正确。
public class Erasure <T extends String>{
// public class Erasure <T>{
T object;
public Erasure(T object) {
this.object = object;
}
}
再看测试结果
Field name object type:java.lang.String
我们现在可以下结论了,在泛型类被类型擦除的时候,之前泛型类中的类型参数部分如果没有指定上限,如 则会被转译成普通的 Object 类型,如果指定了上限如 则类型参数就被替换成类型上限。