为什么实用工厂方法常常使用特定的泛型参数(如
例如,Functions#forPredicate 的签名为:
为什么不使用:
这是否会使得以下类似的内容成为可能?
T
),而不是有界通配符参数(如 ? super T
)?例如,Functions#forPredicate 的签名为:
public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate)
为什么不使用:
public static <T> Function<T, Boolean> forPredicate(Predicate<? super T> predicate)
这是否会使得以下类似的内容成为可能?
Predicate<Number> isPositivePredicate = ...
Function<Integer, Boolean> isPositiveInteger = Functions.forPredicate(isPositivePredicate);
// above line is compiler error:
// Type mismatch: cannot convert from Function<Number,Boolean> to Function<Integer,Boolean>
这是因为期望使用 Function
和 Predicate
的消费者具有必要的有界通配符参数,从而使这种情况不必要吗?例如,Iterables#find 上的通用边界允许在 Iterable<Integer>
上使用 Predicate<Number>
:
public static <T> T find(Iterable<T> iterable,
Predicate<? super T> predicate)
还有其他原因吗?
Predicate<? super T>
可以直接使用,在任何您使用Predicate<T>
的地方都可以使用。无需进行类型转换;它们可以应用于完全相同的值。 - Louis WassermanPredicate
,这似乎可能需要一个包装器来“向上转换”参数,或者在Predicate
本身上进行显式转换。但我想当涉及到多个通配符时,情况可能会变得非常混乱,所以尽可能避免这种麻烦可能是明智的 :) - matts