繁体   English   中英

函数输入类型的通用有界通配符

[英]Generic bounded wildcard of function input type

在阅读Stream接口源代码时,我发现了这个方法签名:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

我想知道为什么mapper的输入类型是? super T ? super T而输出类型是? extends R ? extends R ,为什么不使用? extends 两者都? extends

考虑您要将CharSequence映射到另一个CharSequence (因此T = R = CharSequence )。 哪些功能适合您?

Function<Object, String> fn1 = Object::toString;

对你有好处吗? 是的,因为它可以采用任何 CharSequence (也是Object )并将其转换为String (也是CharSequence )。

Function<CharSequence, StringBuilder> fn2 = StringBuilder::new;

对你有好处吗? 是的,因为它可以接受任何 CharSequence并将其转换为StringBuilder (也是CharSequence )。

Function<String, String> fn3 = String::trim;

对你有好处吗? 不,因为它不能接受任何 CharSequence ,只有其中一些。

因此,您可以看到第一个类型参数必须是CharSequence或任何超类,但第二个必须是CharSequence或任何子类。

因为PECS :) - Producer Extends,Consumer Super

生产者扩展 - 如果您需要一个List来生成T值(您想从列表中读取Ts),您需要声明它? extends T ? extends T

消费者超级 - 如果你需要一个List消耗T值(你想把Ts写入列表),你需要声明它? super T ? super T

Joshua Bloch在他的Effective Java书中首次提到了一个经验法则,即PECS

  • PE制作人延伸
  • CS消费者超级

该函数从接收到的结果( ? super T )产生结果(? extends R) )。

java.util.Function的文档有点清楚:

表示接受一个参数并生成结果的函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM