擦拭法
java的虚拟机是没有泛型类型对象的,所有的对象都属于普通类。
擦拭法
无论什么时候定义一个泛型,编译的时候都会自动的匹配一个相应的原始类。这个原始类名就是去掉类型参数后的泛型类型名。类型变量会被擦除,替换为限定类型,或Object(没有限定时)。
例如一个泛型类Pair如下:
class Pair<T>
{
private T first;
private T second;
public Pair (T first, T second)
{
this.first = first;
this.second = second;
}
public T getFirst()
{
return this.first;
}
public T getSecond ()
{
return this.second;
}
public void setFirst (T first)
{
this.first = first;
}
public void setSecond (T second)
{
this.second = second;
}
}
原始类型如下:
class Pair
{
private Object first;
private Object second;
public Pair (Object first, Object second)
{
this.first = first;
this.second = second;
}
public Object getFirst()
{
return this.first;
}
public Object getSecond ()
{
return this.second;
}
public void setFirst (Object first)
{
this.first = first;
}
public void setSecond (Object second)
{
this.second = second;
}
}
这里因为泛型类T是一个没有限定的变量,所以直接用Object替换。
使用泛型的时候,我们编写的代码也是编译器看到的代码:
Pair<String> p = new Pair<>("Hello", "world");
String first = p.getFirst();
String last = p.getLast();
而虚拟机执行的代码并没有泛型:
Pair p = new Pair("Hello", "world");
String first = (String) p.getFirst();
String last = (String) p.getLast();
所以,Java的泛型是由编译器在编译时实行的,编译器内部永远把所有类型T
视为类处理,但是,在需要转型的时候,编译器会根据T
的类型自动为我们实行安全地强制转型。
限定类型
原始类型用第一个限定来替换类型变量,或者,如果没有给定限定,就替换为Object。
下面看一个使用了限定的泛型类
public static <T extends Comparable> T t (T ...args)
{
T item = args[0];
for (int i=1; i < args.length; i++)
if (item.compareTo(args[i]) > 0)
item = args[i];
return item;
}
原始类型如下:
public static Comparable t (Comparable ...args)
{
Comparable item = args[0];
for (int i=1; i < args.length; i++)
if (item.compareTo(args[i]) > 0)
item = args[i];
return item;
}