问题描述
- 子类调用父类的泛型方法,为何不用强转就能得到正确的类型,父类编译的时候不是泛型擦出了吗?
-
以下面这个简单例子演示:
这是父类public abstract class GenericFather<T> { public T getT(T t){ return t; } }
通过反编译可以得知编译后泛型擦出,T都用Object代替了
也就是说只要调用父类方法最后肯定返回的是个Object类型public abstract class GenericFather { public GenericFather() { } public Object getT(Object t) { return t; } }
那么问题来了,为何子类调用父类方法时可以不用强转就得到正确的类型?问题到底出在哪里?
解决方案
解决方案二:
你可以写个子类继承你的父类,如果你没有指定泛型类型,那么java编译器会默认泛型类型就是Object的,即父类的方法声明默认成了getT(Object)
//编译器给出警告,GenericFather is a raw type. References to generic type GenericFather<T> should be parameterized
public class Son extends GenericFather{
//调用getT时必须制定参数类型就是Object
Son s = new Son();
s.getT(t)
}
如果你指定了泛型的具体类型,那么你调用getT时就是指定的类型了,所以不会无论如何都能正确获取到类型的。
解决方案三:
泛型主要就是用于编译期间的类型约束的,如果你要继承这个带有泛型的父类,就必须指定泛型代表的具体类型,例如
class Child extends GenericFather<T>
这里就不能用,得是具体的类型,并且调用父类方法getT()里传的参数也必须是泛型约束的类型,所以返回的肯定是正确的类型。
所以他不是把Object强转成了正确类型,而是你在编译时候就写成正确类型了
解决方案四:
class Child extends GenericFather<T>
//不能使用<T>,必须是具体类型,例如<Date>
时间: 2024-09-15 06:50:27