灵魂拷问
为什么我们需要泛型?
1, 编译时进行类型检查
2,消除类型转换,不需要强转
3,可以复用函数,实现通用的算法
泛型类,泛型接口和泛型方法。
1,泛型类的定义:
// TODO
如何限定类型变量?
// 规定了泛型 U ,入参必须是 Number 的子类或者本身
public <U extends Number> void inspect(U u) {
System.out.println("T: " + t.getClass().getName());
System.out.println("U: " + u.getClass().getName());
}
泛型使用中的约束和局限性
1, 静态变量不可以使用泛型表示
2,泛型变量不可以通过 new 来实例化
3,泛型变量不可以通过 instanceof 来判断是否是自身
...
泛型类型能继承吗?
两种方式:
1, class Person<T> extends Animal<T>
2, class Person extends Animal<Object>
泛型中的通配符类型
注:通配符,仅可使用在方法中
// extends 限定了入参的上界,上界限定符,可获取,不可修改——只读
public static void process(List<? extends Food> list) { /* ... */ }
// super 限定了入参的下界,下界限定符,可编辑,不可获取—— 只写
public static void process(List<? super Apple> list) { /* ... */ }
虚拟机是如何实现泛型的?
List<Interge> x = new ArrayList<>();
在虚拟机中,等同于:
List<String> x = new ArrayList<>();
他们都相当于:
List<Object> x = new ArrayList<>();
虚拟机中,并未真正实现泛型,我们所申请的泛型变量,在虚拟机中,均会被“类型擦除”