【JAVA】【泛型通配符】【个人总结】<? extends ClassType>、<? super ClassType>中get add方法被限制的原因

<? extends ClassType>、<? super ClassType>中get add方法被限制的原因

问号是通配符,用在声明引用类型的尖括号里,目的解决“苹果的盘子”不是“水果的盘子”之类的问题

class Fruit {}
class Apple extends Fruit {}
class Plate<T>{
    private T item;
    public Plate(){}
    public void set(T t){item=t;}
    public T get(){return item;}
}

定义一个水果盘子,然后直接用苹果盘子去赋值是不行的,也就是说苹果盘子不是水果盘子。

Plate<Fruit> p=new Plate<Apple>();
//error: incompatible types: Plate<Apple> cannot be converted to Plate<Fruit>

这个时候就要用问号通配符告诉编译器,我现在声明的是一个水果及其基类的盘子,也就是这样

Plate<? extends Fruit> p=new Plate<Apple>();

这样的操作会带来下面两个问题:

  1. <? extends ClassType> 不能进行set()或List中的add()操作,也就是不能执行参数列表中含有T的方法。
  2. <? super ClassType>执行get()操作会返回一个Object,也就是返回值为T的方法会返回一个Object。

我们知道在下面两种情况时,ClassTypeB必须和ClassTypeA是相同类型,或者是其派生类。
ClassTypeD 必须和ClassTypeC 是相同类型,或者是其派生类。

public void add(ClassTypeA t){

}
add(new ClassTypeB());
public ClassTypeC get(){
	return new ClassTypeC();
}
ClassTypeD d=get();

同样的,在调用泛型类中的方法时也必须遵守这两条规则,不然就会造成信息丢失。
在这里插入图片描述
假设下列情况

Plate<? extends Fruit> p=new Plate<1>();

这种情下位置【1】可以填写Fruit、Apple、GreenApple三种类。
现在我们现在将【1】的位置填入Fruit的派生类GreenApple.

Plate<? extends Fruit> p=new Plate<GreenApple>();

我们执行p.set(【2】);我们理所当然的认为【2】应该填new GreenApple()而不是Apple或者Fruit,但是编译器只保证p这个盘子的实际类型必须为Fruit或其派生类,但不知道到底是Fruit、Apple、GreenApple中的哪一个。也就是说编译器无法判断你会不会进行下列操作

p.set(new Apple);即GreenApple item=new Apple();基类赋值给子类

所以说,编译器就直接把<? extends Fruit>调用参数列表中含有T的普通方法的权限给禁掉了。

接下来看

Plate<? super Apple> p=new Plate<1>();

这种情下位置【1】可以填写Food、Fruit、Apple三种类。
现在我们现在将【1】的位置填入Apple的基类Food.

Plate<? super Apple> p=new Plate<Food>();

假设我们执行【2】 food=p.get();同样编译器也不知道盘子p的类型究竟是Apple、Fruit还是Food.也就是说如果返回一个确切无法避免下列情况

Fruit fruit=p.get();即Fruit fruit=new Food();基类赋值给子类

但是还有一个解决方案,那就是返回一个Object,因为Object是所有类的基类。所以说<? super ClassType>的get方法会返回一个Object。
如果有错误请帮忙指出。Thanks♪(・ω・)ノ

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值