泛型:1、主要是编译期检测类型是否错误
2、增加代码复用性
运行时转换异常检查提前到编译期检查
泛型类 class<T>
泛型接口 interface<T>
泛型方法 <T> void test(T t) {}
<T> A<T> test(){}
泛型类继承 class A<T> extends class B<T>
class C implements class B<String>
类型参数VS类型实参
Foo<T> T为类型参数 形参
Foo<String> String为类型参数 实参
面试干货:
1、数组Array里面不可以使用泛型
2、泛型类型引用传递问题 List<String>能传递给List<Object>吗?
不可以,没有继承关系
3、Set和Set<?>区别在哪? 带泛型的会被编译器进行类型检查
4、List<?>和List<Object>之前的区别
List<?>是未知类型的集合 List<Object>是任意类型的集合 如果List<String>
是可以传给List<?>的,不可以传给List<Object>的,尽管String是Object的子类,但是List<String>和List<Object>没有任何关系
5、泛型是什么?有什么好处?
泛型是一种参数化的机制
1、类型检测提前到编译期,便于更早发现错误
2、代码复用、灵活、简介
比如:排序算法 参数接受可以接受int double 任意的
泛型工作机制:主要是编译期编译器检查泛型的类型问题,编译成字节码之后,里面就没有泛型了,类型擦除了。(类的常量池保留泛型信息,可以通过反射获取)
泛型PECS PE 生产者 获取数据 producer extends 能读不能写
CS 消费者 增加数据 consumer super 能写不能读
通配符就一个目的:让泛型转型更加灵活
限定通配符 extends super
非限定通配符 ? <?>等价于 <? extends Object>
Plate
Plate<Object> 实参泛型
Plate<?> 不能读不能写 保证泛型检查类型
Plate<T> 形参泛型
Plate<? extends T> 限定通配符 上界 能读不能写
Plate<? super T> 下界 能写不能读
1、java泛型的原理?什么是泛型擦除机制
JDK5引入的特性,为了向下兼容,虚拟机是不支持泛型的,java实现是一种伪泛型,在编译期擦除了泛型信息,java就不需要产生新的类型到字节码,泛型最终都是一种原始类型,java运行时不存在泛型信息
2、java编译器具体如何擦除泛型?
检查泛型类型,获取目标类型
没有限定的类型,用object作为原始类型
有限定的类型,用限定类型作为原始类型
有多个限定的类型,使用第一个边界作为原始类型
必要时插入类型转换保证类型安全
生成桥方法保证扩展时的多态性
3、泛型及泛型擦除的副作用
泛型擦除变成object不能存int,所以泛型不支持基本数据类型
不能用instanceof 擦除后不知道是什么类型,<?>是可以的,未知类型
泛型参数需要创建才能确定,静态的不能直接使用,static T one; static T test(T t)
而static <T> T test(T t)这种是可以的,
泛型擦除后,想同的两个方法不能重载
不能创建泛型类的实例,可以newInstance()反射做到
不能创建泛型数组 A extends B A[] 父类是 B[] 数组的协变(List是不变的)
擦除就不能满足协变的原则
继承异常捕获不行,可以抛出