泛型
/ / 点击 /JAVA中泛型简单讲就是将类型参数化,可以用在类、接口和方法。
泛型类:
1 | public class ClassA<T> { |
泛型接口:
1 | interface IA<T> { |
泛型方法:
1 | public <T> void print(T t) { |
泛型只在编译期有效,编译后生成的字节码中不包含泛型信息,也就是在编译结束后泛型被去除了。即泛型擦除。泛型被擦除后变成了什么呢?
1 | ArrayList<Integer> listA = new ArrayList<>(); |
运行结果:
listA type isclass java.lang.Integer
listA编译后泛型转化成了实际对象类型Integer,也就是自动类型转换。
- 有界通配符
MyClass<? extends Number>
有上限,须继承Number类;
MyClass<? super String>
有下限,须是String类的父类,如Object
- 静态方法不能使用类定义的泛型,因为静态方法调用时,类还没有初始化,且方法在栈中,类的实例化在堆区。
泛型带来的问题:
1.泛型会经过先类型检查再编译,类型检查针对的是引用;
1 | ArrayList<String> list = new ArrayList<>(); |
2.引用传递;1
2
3
4ArrayList<String> list = new ArrayList<>();
t1(list);//编译不通过,类型检测ArrayList<String>与ArrayList<Object>数组结构不一样
private void t1(ArrayList<Object> l) {
}
泛型类型继承规则与普通类继承关系不一样的一点。
3.类型擦除与多态的冲突,如在父类中泛型方法,子类实现的对应方法泛型换作具体类型,在该过程中系统为我们生成了桥方法;
1 | //创建接口IFanSheDuoTai,申明方法,方法参数类型是泛型T; |
反编译FanSheDuoTai.class
javap -p FanSheDuoTai.class
1 | public class com.litchi.demo.FanSheDuoTai implements com.litchi.demo.IFanSheDuoTai<java.lang.String> { |
FanSheDuoTai反编译得到的方法可以看到有test(String)和test(Object),test(Object)就是在泛型编译完成后的桥方法
4.泛型不能是基本数据类型;
5.Gson在运行时使用常量池中泛型标签信息解析数据到泛型;
1 | Type componentType = ((GenericArrayType)type).getGenericComponentType(); |
6.静态方法不能使用类定义的泛型,因为在静态方法调用时,类对象可能还没有实例化,类定义泛型是在类实例化时执行,所在的内存区域也是不一样的。
感谢
https://www.cnblogs.com/huansky/p/8043149.html
https://stackoverflow.com/questions/937933/where-are-generic-types-stored-in-java-class-files