🕒 泛型

吞佛童子2022年10月10日
  • Java
  • 泛型
大约 2 分钟

🕒 泛型

常用泛型符号

  • T
    • 一旦在某个类中确定了具体类型,之后不可再改变
    • Type
  • E
    • Element
  • K
    • key
  • V
    • val
  • ?
    • 不确定的类型
    • 无法将某个具体类赋值给它
    • <? extend T> | <? super T> | <?>
  • Object
    • 所有类的跟类
    • 实例化时,可将任意类赋值给它,存入时,会将存入的类 强制转换为 Object 类

extend VS super

? extend T

  1. 存入的类为 ?, 代表的一个具体的类,为 T 的某个确定子类 或其本身,后续存入的数据必须是 这个确定类,而不能是 T 类的任意一个子类了
  2. 插入元素
    • 因为不确定插入的是 T 的哪个具体子类,因此不能插入任一子类,由于 T 和 T 的父类也不是想要的子类,因此任何类均无法插入
  3. 获取元素
    • 可通过 T cur = list.get(0) 让 T 作为返回类,因为不论是哪个子类,都能用父类表示

? super T

  1. 存入的类为 ?, 代表的一个具体的类,为 T 的某个确定父类 或其本身,后续存入的数据必须是 这个确定类,而不能是 T 类的任意一个父类了
  2. 插入元素
    • 因为不确定是 T 的哪个父类,因此不能插入具体的某个 T 的父类,但可以插入 T | T 的任意子类,子类都可以代表父类
  3. 获取元素
    • 虽然我们无法得知具体的父类,但是所有类的父类是 Object 类,因此可通过 Object object = list.get(0) 得到
// 1. Fruit 的父类
public class Food {}
// 2. Fruit 类
public class Fruit extends Food {}
// 3. Fruit 子类 1
public class Apple extends Fruit {}
// 4. Fruit 子类 2
public class Banana extends Fruit{}

public class GenericTest {

    // 1. extend 验证
    public void testExtends(List<? extends Fruit> list){

        //报错,extends为上界通配符,只能取值,不能放.
        //因为Fruit的子类不只有Apple还有Banana,这里不能确定具体的泛型到底是Apple还是Banana,所以放入任何一种类型都会报错
        //list.add(new Apple());

        //可以正常获取
        Fruit fruit = list.get(0);
    }

    // 2. super 验证
    public void testSuper(List<? super Fruit> list){

        //super为下界通配符,可以存放元素,但是也只能存放当前类或者子类的实例,以当前的例子来讲,
        //无法确定Fruit的父类是否只有Food一个(Object是超级父类)
        //因此放入Food的实例编译不通过
        list.add(new Apple());
        //list.add(new Food());

        Object object = list.get(0);
    }
}

<?> VS <Object>

  • 可以将 List<String> | List<Integer>赋值给 List<?>,却不能把 List<String> 赋值给 List<Object>
上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou