java 泛型 et_Java 泛型通配符

# 假设

class Food {}

class Fruit extends Food {}

class Apple extends Fruit {}

class Orange extends Fruit{}

# ? extends class

extends 很直接明了,继承。这句话含义:某个类继承了 class。例如 ? extends Fruit,意思是某个类继承了 Fruit,可以是 Orange 等等。

插入数据:完全不可以。当类型擦除时,编译器只能知道他是某个继承了 class 的类,并不能确定是什么类,插入数据容易引起类型错误。

可以举个例子,现在有一个方法,public void add(ArrayList extends Fruit> fruit) {fruit.add(new Apple());},暂时不对判断对错,先分析。

假设,ArrayList 指向的是 ArrayList,那没问题;假设指向的是 ArrayList,那显然类型转换错误。

Object 也不能插入,Object 并没有继承 Fruit。

所以为了类型安全起见,必须让 fruit.add(new Apple()) 产生编译错误。

读取数据:完全可以。既然是继承了 class 的类,必然可以将其中元素向上转型成 class 取出。

可以举个例子,现在有一个方法,public void get(ArrayList extends Fruit> fruit) {fruit.get();},暂时不对判断对错,先分析。

假设 ArrayList 指向的是 ArrayList,将取出来的 Apple 向上转型为 Fruit;假设指向的是 ArrayList,将取出来的 Orange 向上转型为 Fruit。

故可行。

# ? super class

super 很直接明了,被继承。这句话含义:某个类被 class继承。例如 ? super Fruit,意思是某个类被 Fruit 继承,可以是 Food 等等。

插入数据:部分可以。当类型擦除时,编译器可以知道它至多是类 class,可以将继承 class的类向上转型之后插入,而非继承 class的类,向下转型不能保证成功,所以不能加入。

可以举个例子,现在有一个方法,public void add(ArrayList super Fruit> fruit) {fruit.add(new Apple())},暂时不对判断对错,先分析。

这个 ArrayList 插入 Apple,那是没问题的,不过这个 Apple 要向上转型;那如果指向的是 ArrayList 呢?也没有问题,把 Orange 向上转型,反正 ArrayList super Fruit> 顶层就是一定有 ? extend Fruit 这个类了。

故可行。

Objecet也不能插入。准确的来说,被 class 继承的类,都不能插入。

可以举个例子,现在有一个方法,public void add(ArrayList super Fruit> fruit) {fruit.add(new Object())},暂时不对判断对错,先分析。

这个 ArrayList 实际指向的是 ArrayList,那是没问题的,不过这个 Apple 要向上转型;那如果指向的是ArrayList呢?Object 不是 Food,无法将插入的 Object 转换为 Food。

所以为了类型安全起见,必须让 fruit.add(new Object()) 产生编译错误。

读取数据:很别扭,但是可以。编译器可以知道它至多是类 class,但并不能知晓是 class 的哪一个父类,所以只能转换为最基础的父类——Object。

可以举个例子,现在有一个方法,public void get(ArrayList super Fruit> fruit) {fruit.get();},暂时不对判断对错,先分析。

假设 ArrayList 可能指向的是 ArrayList,也可能指向的是 ArrayList,最保险做法是返回 Object——这肯定没错。

故可行。

# 总结

作为一个开发者来说,Java 的泛型很糟糕,机制过于复杂。

作为构造 Java 的人来说,Java 的泛型很伟大,它保证了向后兼容性。

PECS原则:

如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends class通配符(Producer Extends)

如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super class通配符(Consumer Super)

如果既要存又要取,那么就不要使用任何通配符

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值