为什么谷歌集合包含语义相等的函数和奇怪的泛型



为什么谷歌集合或番石榴包含语义相等的函数?示例:

static
<T> Predicate<T>
and(Predicate<? super T>... components) 
static
<T> Predicate<T>
and(Predicate<? super T> first, Predicate<? super T> second) 

即所有可以接受几个参数的函数。

第二个问题是,为什么这些函数的定义使用泛型<? super T>而不是<T>

要回答第一个问题,varargs版本(Predicate<? super T>...)将在使用多个泛型谓词(例如Predicate<T>)调用时向您发出关于未检查创建泛型数组的警告。对于组合两个谓词的常见情况,您不会得到警告。

为了回答第二个问题,取Predicate<? super T>意味着在调用创建Predicate<Integer>的方法时可以传入Predicate<Object>(或Predicate<Number>或其他)。例如,如果Predicates.notNull()Predicate<Object>(应该是这样),并且您希望将其与某些Predicate<Integer>组合在一起,那么如果参数的类型要求为Predicate<T>,则这是不可能的。

我相信第一部分是为了性能。

在第二部分中,它必须是<? super T>,因为Guava允许你放入任何谓词,这些谓词可以在T的任何超类型和T本身上求值。不仅仅是T本身,因为它只会有<T>。这是有道理的,因为特定的谓词可能更通用,因此是在更通用的类型上定义的,但您希望将其与某些子类型一起使用。

树集构造函数TreeSet(Comparator<? super E> c)也是如此。

另请参阅Generics教程第18页

最新更新