由于 java 使用擦拭法来实现泛型,导致编译器把类型<T>
视为``Object,同时编译器根据
-
<T>
不能是基本类型,比如int
、double
等,因为泛型的实际类型是Object
,而Object
类型无法持有基本类型。 -
无法取得带泛型的
Class
,因为<T>
是Object
类型,在编译后,所有泛型实例的getClass
返回的是同一个Class
实例。 -
无法判断带泛型的
Class
。例如:
Pair<Integer> p = new Pair<>(123, 456); // Compile error: if (p instanceof Pair<String>.class) { } // 并不存在 Pair<String>.class,而是只有唯一的 Pair.class。
-
不能实例化
T
类型。例如:
public class Pair<T> { private T first; private T last; public Pair() { // Compile error: first = new T(); last = new T(); } } // first = new T(); 在擦拭后实际变成了 first = new Object(); 这样的话,创建的所有泛型到头来全成 Object 了。
如果要实例化的话,需要借助
Class<T>
参数:public class Pair<T> { private T first; private T last; public Pair(Class<T> clazz) { first = clazz.newInstance(); last = clazz.newInstance(); } }
上述代码借助
Class
参数并通过反射来实例化T
类型,使用的时候,也必须传入Class
。例如:Pair<String> pair = new Pair<>(String.class);
Java 的泛型是采用擦拭法实现的;
擦拭法决定了泛型<T>
:
-
不能是基本类型,例如:
int
; -
不能获取带泛型类型的
Class
,例如:Pair.class
; -
不能判断带泛型类型的类型,例如:
x instanceof Pair
; -
不能实例化
T
类型,例如:new T()
。
泛型方法要防止重复定义方法,例如:public boolean equals(T obj)
;
子类可以获取父类的泛型类型<T>
。
本文转载并精简自 https://www.liaoxuefeng.com/wiki/1252599548343744/1265104600263968