# 泛型
- 本质: 类型参数化
# 类型擦除
- java的泛型在编译期间会被檫掉
- 如何保证类型安全: java编译器先检查泛型类型,再进行类型擦除,最后进行编译
- 类型擦除与多态冲突解决方法: 桥方法 (子类继承父类的泛型方法,本应该重写,由于类型擦除,变为了重载)
# 桥方法
class A<T>{
void setValue(T param);
T getValue();
}
class B extends A<String>{
void setValue(String param);
String getValue();
}
class A_compilied{
void setValue(Object param);
Object getValue();
}
//编译后的方法
class B_comiplied extends A_compilied{
void setValue(String param);
String getValue();
//桥方法
void setValue(Object param){
setValue((String)param);
}
//直接写代码时,不能仅靠返回值区分函数,编译不通过。 但是编译器本身可以处理这种情况
//协变返回类型
Object getValue(){
getValue();
}
}
class Test{
public static void main(String[] args) {
//解决多态冲突的问题
A a = new B();
a.setValue("aaa");
System.out.println(a.getValue());
//正常调用
B b = new B();
b.setValue("ccc");
b.getValue();
}
}
# 泛型的好处
- 类型安全
- 消除强制类型转换
# 获取泛型类型
- 将 类(Type) 强转 为 ParameterizedType
- 调用反射获取泛型类型数组,getActualArgumentsArgs();
- 只能通过对象反射获取泛型类型。 无法直接通过类获取到反射信息.
public class GetTTest {
public static void main(String[] args) {
//报错,因为获取到的父类Type为 Object,无法强转
// A a = new A();
// System.out.println(a.getTType());
// B b = new B();
// System.out.println(b.getTType());
Type type = C.class;
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] types = parameterizedType.getActualTypeArguments();
for (Type type1 : types) {
System.out.println(type1);
}
// C c = new C();
// System.out.println(c.getTType());
}
public static class A<T>{
public Class<T> getTType(){
Type type =getClass().getGenericSuperclass();
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] types= parameterizedType.getActualTypeArguments();
for (Type type1 : types) {
System.out.println(type1);
}
return (Class<T>) types[0];
}
}
public static class B extends A<Integer>{
}
public static class C<T> extends A<T>{
}
}