Caros,
Dado o seguinte código,
List<? super String> listaString = new ArrayList<String>();
não é possível fazer algo do tipo
listaString.stream().map(s -> s.toUpperCase()).forEach(System.out::println);
pois o <? super String> indica que podemos referenciar uma lista de qualquer tipo que seja superclasse de String, e não faz sentido chamar o método toUpperCase() caso tenhamos uma List< Object >, por exemplo. Sendo assim, por que o código a seguir compila?
Predicate<? super String> predicadoString = str -> str.length() > 2;
Da mesma forma que na declaração da lista, o wildcard <? super String> indica um supertipo de String. Não temos garantia de que este tipo possui um método length(). Por que este segundo exemplo compila?
E para completar, por que a seguinte atribuição é válida
Predicate<Object> predicadoObjeto = obj -> true;
predicadoString = predicadoObjeto;
porém a chamada a seguir resulta em erro:
System.out.println(predicadoString.test(new Object()));