Why google-collections contains semantically equal functions and strange generics?
Why google-collections or guava contains semantically equal functions? e开发者_StackOverflow中文版xample:
static
<T> Predicate<T>
and(Predicate<? super T>... components)
static
<T> Predicate<T>
and(Predicate<? super T> first, Predicate<? super T> second)
I.e. all functions that can accept several arguments.
The second question why do defintion of such functions use generic <? super T>
instead of <T>
?
To answer the first question, the varargs version (Predicate<? super T>...
) will give you a warning about the unchecked creation of a generic array when called with several generic predicates (e.g. Predicate<T>
). For the common case of combining two predicates, you don't get that warning.
To answer the second question, taking Predicate<? super T>
means you can pass in a Predicate<Object>
(or Predicate<Number>
or whatever) when calling the method to create a Predicate<Integer>
. For example, if Predicates.notNull()
were a Predicate<Object>
(as it should be) and you wanted to combine that and some Predicate<Integer>
, it would not be possible if the arguments were required to be of type Predicate<T>
.
First part is for performance, I believe.
In the second part it have to be <? super T>
, because Guava allows you to put in any Predicate which can be evaluated on any super-type of T and T itself. Not only T itself as it would be with just <T>
.
This makes sense due to the fact that a specific Predicate may be more general and is therefore defined on a more general type but you want to use it with some sub-type.
You see the same with the TreeSet Constructor: TreeSet(Comparator<? super E> c)
.
Also have a look at Generics Tutorial Page 18
精彩评论