如何解决java.util.Function源代码通配符边界用法的理解
试图了解java.util.Function
的源代码
在将我的版本与源代码进行比较时,尝试创建我自己的此类版本,发现了一个区别-无法理解使用泛型类型边界的原因。
myVersion
default <V> MyFunction<T,V> andThen(MyFunction<? super R,V> after) {
return t -> after.apply(apply(t));
}
javaSource
default <V> Function<T,V> andThen(Function<? super R,? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
除了使用java.util.Function
代替andThen
之外,此方法与? extends V
V
方法几乎相同。
为什么在? extends V
方法中使用类型上限andThen
-是否有仅适用于? extends V
而不适用于V
的方案? strong>
注意:我理解? super R
部分是必需的,因为没有它,我们将只能链接另一个输入参数类型与R
完全相同的函数
对? super V
方法中compose
的用法也有相同的疑问
解决方法
Function
界面和您的MyFunction
界面在设计时都应考虑PECS(注释中已经提供了链接What is PECS (Producer Extends Consumer Super)?)。
虽然MyFunction
可以编译并与简单的返回类型V
一起使用,但可以使其更加灵活。这个示例可能有些人为,但是它说明了可以通过将其设置为? extends V
来增加灵活性。
MyFunction<Integer,Integer> first = x -> x + 1;
MyFunction<Integer,Integer> second = x -> x * 2;
MyFunction<Integer,Number> andThen = first.andThen(second);
除非您使返回类型包括? extends V
,否则最后一行将不会编译。这允许声明一个函数变量以返回更大的类型。 V
推断为Number
,而? extends V
部分则允许它采用返回子类型Integer
的函数。
当人们需要这种灵活性时会发生什么,例如当返回类型可能不是Integer
而是Number
时?
MyFunction<Integer,Double> third = x -> x / 3.0;
andThen = first.andThen(third);
当您需要编写可能在同一对象层次结构中返回不同类型的函数时,这很有用。 Integer
或Double
都是Number
。如果将返回类型限制为V
,则无法实现这种灵活性。变量andThen
不能同时用于andThen
调用的两个结果。
当然,您可以强制变量类型与andThen
的返回类型相同,但是没有理由限制用户调用代码的灵活性。
生产者扩展了灵活性。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。