1、首先要知道泛型是什么?
- 泛型就是一种不确定的数据类型。本质是参数化类型。
- 没有泛型的时候,通过对类型 Object 的引用,假设时子类String实现,那么则编译器不会对静态类型Object做限制,输入可以是任意类型,比如Integer。然后输出时,
强制类型转换
为实现的子类String时,就会报错。这存在安全隐患
- 泛型的好处就是编译的时候能够检查类型安全,并且所有强制转换都是自动隐式的
- 我创建一个List< String>类型的引用,用ArrayList< String>()赋值。那么编译器检查我输入的会是不是String
List<String> listObject = new ArrayList<String>();
listObject.add("");
2、想参照父类声明子类实例化写泛型类似的功能-❌
- 不能如下写,虽然A extends B 但是ArrayList< A>和ArrayList< B>,没有一毛钱关系,不可能赋值成功。
Object object = new String();
1.3、泛型通配符解决了上述问题
- 声明一个水果及其子类都能用的盘子,然后实现时,用苹果具体化。先看一个上述的一个❌具体的错误用法
- 那么我声明一个水果及其子类都能用的盘子,然后实现时,用苹果具体化,该怎么办呢?
Plate<? extends Fruit> p1 = new Plate<Apple>(new Apple());
- 那么我定义一个水果及其父类类都能用的盘子,然后用食物,也就是其父类去赋值当然是可以啦
Plate<? super Apple> p2=new Plate<Fruit>(new Fruit());
<? extends ClassType>、<? super ClassType>中get add方法被限制的原因
- 问号是通配符,用在声明引用类型的尖括号里,目的解决“苹果的盘子”不是“水果的盘子”之类的问题。
Plate<? extends Fruit> p1 = new Plate<Apple>(new Apple());
Fruit fruit = p1.get();
Plate<? super Apple> p2=new Plate<Fruit>(new Fruit());
p2.set(new Apple());
Object object = p2.get();