【从零开始学Java | 第二十四篇】泛型的继承和通配符
目录前言一、泛型的继承二、泛型的通配符总结前言在上一篇博客中我们认识了泛型它会帮我们在编译器就拦截了类型转换异常。但是当泛型遇到继承呢既然Integer继承自Number那ListInteger是不是ListNumber的子类答案是否定的接下来对这一知识点进行详细说明。一、泛型的继承泛型不具备继承性但是数据具备继承性。为什么Java不允许ListAnimal list new ArrayListDog()这样操作呢如果这行代码编译通过了animalList表面是一个可以装所有动物的集合。那是不是说明一个继承自Animal类的Cat类也能存入animalList中。但是animalList实际上是ArrayListDog等你想把它当狗拿出来的时候程序就会崩溃。数据具备继承性public class GenericsTest01 { public static void main(String[] args) { ListAnimal animalList new ArrayList(); animalList.add(new Animal()); animalList.add(new Dog()); } } class Animal {} class Dog extends Animal {}二、泛型的通配符现在有这样一个场景需要定义一个方法形参是一个集合但是集合中的数据类型不确定应该怎么做一般方法使用泛型方法public class GenericsTest02 { public static void main(String[] args) { } public static E void method(ArrayListE list){ } }存在缺陷利用泛型方法此时它可以接收任意的数据类型public class GenericsTest02 { public static void main(String[] args) { ArrayListAnimal al1 new ArrayList(); ArrayListDog al2 new ArrayList(); ArrayListStudent al3 new ArrayList(); method(al1); method(al2); //这也是对的 method(al3); } public static E void method(ArrayListE list){ } } class Animal {} class Dog extends Animal {} class Student {}但是我们通常希望尽可能传递Animal类及其子类此时就引出了泛型的通配符①上限限制? extends T表示泛型类型必须是T本身或者是T的子类。②下限限制? super T表示泛型类型必须是T本身或者是T的父类。此时上述修改后的方法为此时传递Student类时方法就会报错但是传递Dog就不会。泛型的通配符可以限定类型的范围。应用场景1.如果我们在定义类、方法、接口时如果类型不确定就可以定义泛型类、泛型方法、泛型接口。2.如果类型不确定但是能知道以后只能传递某个继承体系中的类就可以使用泛型的通配符。总结泛型无继承ListDog不是ListAnimal。?无界通配符能接万物但只能读不能写。? extends T规定了上限。安全地读取出 T。? super T规定了下限。安全地写存入 T 的子类。