0
点赞
收藏
分享

微信扫一扫

Java 泛型通配符(PECS法则)

艾晓雪 2022-12-03 阅读 123


PECS法则

PECS 法则​: Producer Extends, Consumer Super

  • 如果参数化类型表示一个生产者,就使用 ​​上界通配符​​ <? extends T>
  • 如果它表示一个消费者,就使用 ​​下界通配符​​ <? super T>

 
或者

  • 如果你想从一个数据类型里获取数据(生产者),使用 ​​上界通配符​​ <? extends T>
  • 如果你想把对象写入一个数据结构里(消费者),使用 ​​下界通配符​​ <? super T>

 
或者

  • 作为生产者提供数据(往外读取)时,适合用上界通配符(extends);
  • 作为消费者消费数据(往里写入)时,适合用下界通配符(super)。

 

Collections.copy() 源码

/**
* @version JDK 1.8
* @param dest The destination list 消费者
* @param src The source list 生产者
*
* 数据流: src(生产者) -> desc(消费者)
* */
public class Collections {
// ...

public static <T> void copy(List<? super T> dest, List<? extends T> src) {
int srcSize = src.size();
if (srcSize > dest.size())
throw new IndexOutOfBoundsException("Source does not fit in dest");

if (srcSize < COPY_THRESHOLD ||
(src instanceof RandomAccess && dest instanceof RandomAccess)) {
for (int i=0; i<srcSize; i++)
dest.set(i, src.get(i));
} else {
ListIterator<? super T> di=dest.listIterator();
ListIterator<? extends T> si=src.listIterator();
for (int i=0; i<srcSize; i++) {
di.next();
di.set(si.next());
}
}
}

// ...
}

 

泛型擦除

private void query(List<String> params) {
// ...
}

private void query(List<Integer> params) {
// ...
}

​List<String>​​​、​​List<Integer>​​​ 擦除后的类型为 ​​List​

反编译之后的方法代码如下

private void query(List params) {}

 

private void query(List<? extends String> params) { 
// ...
}

private void query(List<? super Integer> params) {
// ...
}

​List<? extends E>​​​、​​List<? super E>​​​ 擦除后的类型为 ​​List<E>​

反编译之后的方法代码如下

private void query(List<E> params) {}

 

参考

  • ​​一文读懂Java泛型中的通配符 ?​​


举报

相关推荐

0 条评论