При изучении потоков Java8 я наткнулся на следующий фрагмент кода:
Predicate<? super String> predicate = s -> s.startsWith("g");
Поскольку общий параметр является нижней границей, я решил, что это не скомпилируется. То, как я это вижу, если объект является супертипом для String, то передача объекта типа должна его разорвать, так как Object не имеет функции startWith(). Однако я был удивлен, увидев, что он работает без проблем.
Далее, когда я изменил предикат, чтобы взять верхнюю границу:
<? extends String>,
он не будет компилироваться.
Я думал, что понял смысл верхней и нижней границ, но, очевидно, я что-то упускаю. Может ли кто-нибудь объяснить, почему нижняя граница работает с этой лямбдой?