Java中的泛型 --- Java 编程思想 (2)

​ Java 中的泛型,在编译时,T代表一种类型,如果没有指定任何的边界,那么他就相当于 Object 。 我们可以通过 extends 关键字,给泛型指定边界。 上面代码我们为了能够调用f(), 我们可以协助泛型类,给定泛型类的边界,告诉编译器必须接受遵循这个边界的类型。这里用 extends 关键字。 将上面代码改成

public class HasF{ public void f(){ System.out.println("HasF::f()"); } } class Manipulator<T extends HasF>{ private T obj; public Manipulator(T obj){ this.obj = obj; } public void manipulator(){ obj.f(); } public static void main(String[] args){ HasF hf = new HasF(); Manipulator<HasF> manipulator = new Manipulator<>(hf); manipulator.manipulator(); } }

输出:HasF::f()

这样子在编译的时候就相当告诉编译器 Manipulator 类中 obj 的参数类型 为 HasF 或着它的子类。

? extends T

? 是泛型表达式中的通配符。 ? extends T 表示: T 数据类型或着 T 的子类数据类型。 举个例子

class Vegetables{} // 白菜 class Cabbage extends Vegetables{} // 小白菜 class Pakchoi extends Cabbage{} //大蒜 class Garlic extends Vegetables{} public class Main{ public static void main(String[] args) { // 这个是会报错的。 // ArrayList<Vegetables> vegetables = new ArrayList<Cabbage>(); } }

​ 上面的中 main 方法里面是报错的因为,ArrayList表示这个ArrayList容器中只能存放蔬菜,new ArrayList() 表示 这个使一个只能放白菜的容器。这两个容器是不可以相等的,类型不一样。但是我们可以通过 ? extends T 来解决这个问题,代码如下:

public class Main{ public static void main(String[] args) { ArrayList<? extends Vegetables> vegetables = new ArrayList<Cabbage>(); // 报错 不能添加白菜进去 // vegetables.add(new Cabbage()); } }

​ 我们可以用 vegetables 表示 new ArrayList(), 这是向上转型。但是,为什么 vegetables.add(new Cabbage()) ; 会报错,因为 ArrayList<? extends Vegetables> 表示这个 ArrayList 容器中能够存放任何蔬菜。 但是 ArrayList 具体是什么容器,完全不知道,add 的时候,你添加什么东西进去到这个容器中都是不安全的。 这个时候,我们可以用 ? super T 来进行操作,具体往下看。

? super T

? super T 表示: T 数据类型 或着 T的超类数据类型, super 表示超类通配符。 上面代码可以用以下表示

public class Main{ public static void main(String[] args) { ArrayList<? super Cabbage> cabbages = new ArrayList<Vegetables>(); cabbages.add(new Cabbage()); cabbages.add(new Pakchoi()); // cabbages.add(new Vegetables()); System.out.println(cabbages); } }

上面 ArrayList<? super Cabbage> 表示ArrayList这个容器中怎么都可以存放 Cabbage 以及Cabbage子类的数据类型。 cabbages 指向的是 蔬菜的容器类。 add 进去的是白菜以及白菜的子类型数据。这个当然是支持的。

? extends T VS ? super T

? extends T ,? super T 一般用于方法参数列表。

public class Main{ public static void main(String[] args) { List<Cabbage> cabbages = new ArrayList<>(); cabbages.add(new Cabbage()); cabbages.add(new Cabbage()); cabbages.add(new Cabbage()); extendsTest(cabbages); List<? super Cabbage> list = superTest(new ArrayList<Vegetables>()); System.out.println(list); } public static void extendsTest(List<? extends Vegetables> list){ for (Vegetables t : list){ System.out.println(t); } } public static List<? super Cabbage> superTest(List<? super Cabbage> list){ list.add(new Cabbage()); list.add(new Pakchoi()); return list; } }

? extends T 表示消费者 list 然后把里面的数据消费掉。
? super T 表示生产者 传入一个list 然后往里面添加数据,进行其他操作。

总结

​ 对于 ? extends Class ,? extends T,? super T,不是很理解的,可以自己把例子写一下,然后想一想。Java 泛型的特性在很多开源的框架上是用的非常多的。这快需要深入的理解一下,我想随着敲代码的年限上,应该到了后面会有不一样得理解吧。现在通过书上能够知道,理解得就只有这么多了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgpfg.html