java pecs_Java 泛型 PECS

在stackoverflow上看到两篇关于java泛型 PECS 的问答:

PECS

Remember PECS:"Producer Extends,Consumer Super"

"Producer Extends" - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? extends T, e.g. List extends Integer>. But you cannot add to this list.

"Consumer Super" - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? super T, e.g. List super Integer>. But there are no guarantees what type of object you may read from this list.

If you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g. List.

也就是说:

当你仅仅需要从List中读出T,那么你需要使用? extends T.例如List extends Integer>

当你仅仅需要将T写入List时,那么你需要使用? super T.例如List super Integer>

当你既需要读也需要写时,你应该直接使用T. List< Integer>

PECS的使用

extends

List extends Number> foo 表示foo可以存储一族的类型的值(而不是一个特殊的类型的值),所以下面的声明都是正确的:

List extends Number> foo = new ArrayList; // Number "extends" Number

List extends Number> foo = new ArrayList; // Integer extends Number

List extends Number> foo = new ArrayList; // Double extends Number

正因为foo表示存储的是一族的类型的值,无法保证具体指向的类型,所以我们无法保证我们add的对象是List允许的类型。假如我们add一个Integer的值,但是foo可能指向Double(第三条语句),我们add一个Double的值,foo可能指向Integer(第二条语句)。

虽然无法add,但是我们可以保证我们从foo中取出来的值肯定是属于Number或者是Number的子类,所以我们可以从foo中获取值。

super

关于List super T>,以下声明是正确的:

List super Number> foo = new ArrayList; // Number is a "super" of Number

List super Number> foo = new ArrayList; // Object is a "super" of Number

因为foo的类型无法确定,可能是Number,也可能是Number的父类,我们无法保证读出来的值的类型,所以无法从List中读出值。但是我们可以保证我们插进去的值肯定属于Number或者Number的父类,因此我们可以使用add

JDK中的例子

Collections.copy()的方法签名:

public static void copy(List super T> dest,List extends T> src)

src中,我们可以传入与T类型相关的List,并且能够保证取出的是T类型或者T的子类型的值。

dest中,我们可以传入T类型和T的父类的List,并且能够保证我们从存放的值都满足要求。

例如:

// copy(dest, src)

Collections.copy(new ArrayList(), new ArrayList

Collections.copy(new ArrayList(), new ArrayList

Collections.copy(new ArrayList(), new ArrayList());

Collections.copy(new ArrayList(), new ArrayList

有兴趣的同学可以去看原文。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值