为什么在功能接口中使用下界
Why lower bound is used in functional interfaces
我或多或少清楚集合上下文中下界的用法(参见 PECS question)。 Java 中的功能接口并非如此。例如。为什么 Optional.map 方法具有类型限制较低的签名:
<U> Optional<U> map(Function<? super T, ? extends U> mapper);
这里使用super有什么好处,为什么下面的代码不能编译?
public static void main(String[] args) {
Function<? super BigDecimal, ? extends Number> mapper = dec -> dec
.divide(BigDecimal.TEN)
.doubleValue();
BigDecimal bigD = BigDecimal.ONE;
//works
Optional.of(bigD).map(mapper);
Number number = BigDecimal.ONE;
// the following does not compile,
// despite Number is super type of BigDecimal
Optional.of(number).map(mapper);
}
map
的 mapper
参数中的下限的目的是扩大可接受的 Function
的范围,不仅包括那些 Function
有 正好 T
,还有 T
可能是子类的那些类型。例如。这样的 Optional<BigDecimal>
不仅可以接受 Function<BigDecimal, Number>
,还可以接受 Function<Number, Number>
,因为 BigDecimal
是 Number
。这样的函数应该能够在 BigDecimal
上运行,因为它需要 Number
.
您的行 Optional.of(number).map(mapper);
无法编译,因为此处 T
是 Number
,而不是 BigDecimal
。试图传入 T
为 BigDecimal
的 Function
与签名不匹配——BigDecimal
不是 Number
的超类型。你在这里利用 ? super T
的尝试失败了,因为你使用了不同的 T
,而不是因为它以某种方式失败了 ? super T
。这是两个不同的概念。
我或多或少清楚集合上下文中下界的用法(参见 PECS question)。 Java 中的功能接口并非如此。例如。为什么 Optional.map 方法具有类型限制较低的签名:
<U> Optional<U> map(Function<? super T, ? extends U> mapper);
这里使用super有什么好处,为什么下面的代码不能编译?
public static void main(String[] args) {
Function<? super BigDecimal, ? extends Number> mapper = dec -> dec
.divide(BigDecimal.TEN)
.doubleValue();
BigDecimal bigD = BigDecimal.ONE;
//works
Optional.of(bigD).map(mapper);
Number number = BigDecimal.ONE;
// the following does not compile,
// despite Number is super type of BigDecimal
Optional.of(number).map(mapper);
}
map
的 mapper
参数中的下限的目的是扩大可接受的 Function
的范围,不仅包括那些 Function
有 正好 T
,还有 T
可能是子类的那些类型。例如。这样的 Optional<BigDecimal>
不仅可以接受 Function<BigDecimal, Number>
,还可以接受 Function<Number, Number>
,因为 BigDecimal
是 Number
。这样的函数应该能够在 BigDecimal
上运行,因为它需要 Number
.
您的行 Optional.of(number).map(mapper);
无法编译,因为此处 T
是 Number
,而不是 BigDecimal
。试图传入 T
为 BigDecimal
的 Function
与签名不匹配——BigDecimal
不是 Number
的超类型。你在这里利用 ? super T
的尝试失败了,因为你使用了不同的 T
,而不是因为它以某种方式失败了 ? super T
。这是两个不同的概念。