I have trouble understanding following code about two Predicate
objects. The first one uses a lower bounded wildcard, the second a upper bounded.
Predicate<? super String> p1 = s -> s.startsWith("a"); // why can I call startsWith()?
Predicate<? extends String> p2 = s -> s.startsWith("a");
p1.test("a"); // works
p2.test("a"); // doesn't work (why?)
What I don't understand about p1
is, why is it possible to call methods from the class String
, e.g. startsWith()
? Why can I only pass String
objects into p1.test()
, I expected to be able to call it for Number
and Object
objects as well.
As p1
behaves I thought p2
would, but this isn't the case. I can't even pass a String
object into p2.test()
. This doesn't makes sense to me, because we expect an object which inherits from String
(including String
).
I think it maybe has something to do with the fact, that we specify the reference type rather than the type of the object itself. But what type is then used for the object?