I'm preparing for OCP certificate, and I came across with the idea of a lower bounded wildcard. If I understand it correctly, the lower bounded wildcard is used when we want to let Java know the "bounded type" can always be added to our generic Collection.
For example:
public static void addInteger(List<? super Integer> list, Integer i)
{
list.add(i);
}
public static void main(String[] args)
{
List<Number> list = new ArrayList<>();
addInteger(list, 100);
addInteger(list, 200);
System.out.println(list); // [100,200]
}
Since "? super Integer" indicates that the type must be an Integer or its superclass, adding an Integer to the list will work in each case.
However, this code still compiles and runs like normal:
public static void main(String[] args)
{
Predicate<? super String> pred = s -> s.startsWith("M"); // still compiles
System.out.println(pred.test("Mon")); // Output true
}
Now we have a Predicate that will take 1 parameter which is a String or its super class, but we're not sure it's actually a String or not (What if it's just an Object?). However, we can still access startsWith() method like s is actually a String.
Why does this happen? Please explain to me.