In the find() example, T can always be inferred unambiguously.
In the example forPredicate[1]() T, you can also derive it uniquely.
In the example forPredicate[2]() there is uncertainty about what should be T If the result of the method is assigned to the target type, T can be determined from the target type. Otherwise, it will scratch your head a bit:
forPredicate(isPositive).apply(42);
In java5 / 6, it should not compile. (well, I tested it on java 6 and it compiles, but this is probably a bug, since java 6 also compiles forPredicate(p).apply("str") )
Java 7 has improved a bit, and the new rule has dictated that T=Number . It works, but for him it is more like arbitration.
Ideally, we donโt need to worry about wildcards. If I need a predicate for my integers, I must declare the Predicate<Integer> parameter. The fact that the Predicate<Number> argument is also acceptable is another story. There must be a compiler task for converting Predicate<Number> to Predicate<Integer> - we can do this without overhauling the existing type system of generated java generics, this requires a new conversion rule. You can also provide a transformation library
Predicate<Number> pn = ...; Predicate<Integer> pi = convert(pn); Iterable<Integer> iter1 = ...; Iterable<Number> iter2 = convert(iter1);
All convert() methods can be generated mechanically.
Java 8 makes things easier. We still can not do
Predicate<Number> pn = n -> n.intValue()>0; Predicate<Integer> pi = pn;
but we can do
Predicate<Integer> pi = pn::test; // ok // it means pi = (Integer i)->pn.test(i)
and
Function<Integer, Boolean> f = pn::test;
which is equivalent to f = forPredicate[2](pn) . In java 8, we rarely need forPredicate() , etc. To convert between functional types.