Generics hell: hamcrest matcher como parámetro de método

Entonces, tengamos una lista de cadenas y una función que toma un emparejador Hamcrest y devuelve un resultado dematches() Método del matcher proporcionado:

public boolean matchIt(final Matcher<? super List<String>> matcher) {
    final List<String> lst = obtainListFromSomewhere();
    return matcher.matches(lst);
}

Hasta ahora tan bueno. Ahora puedo llamar fácilmente:

matchIt(empty());
matchIt(anything());
matchIt(hasItem("item"));
matchIt(everyItem(equalToIgnoringCase("item")));

... ya que todos estos métodos estáticos de fábrica producen un comparador que se ajusta a la firma del métodoMatcher<? super List<String>>.

Sin embargo, creo que un emparejador que acepta un Iterable de objetos debe ser aceptado por elmatchIt() método también:

matchIt(everyItem(anything()));

Así que ingenuamente cambié elmatchIt() método de firma:

public boolean matchIt(final Matcher<? super List<? super String>> matcher);

Pero no funciona en absoluto. No solo no acepta.everyItem(anything()), ni siquiera acepta lo previamente correctoeveryItem(equalToIgnoringCase("item")) diciendo (1.7.0_05 versión del compilador):

actual argument Matcher<Iterable<String>> cannot be converted to Matcher<? super List<? super String>> by method invocation conversion

¿Que? Entonces, ¿qué está mal aquí? Es elmatchIt() método de firma o es eleveryItem() ¿Firma de Hamcrest mal diseñada? ¿O es solo que el sistema de genéricos de Java no se puede reparar? Muchas gracias por tus comentarios!

EDITAR @rlegendi mi intención aquí es proporcionar una interfaz para que el cliente agregue y ejecute predicados sobre la lista. Eso esmatchIt() método. VocaciónmatchIt(anything()) Tiene sentido en este escenario, el cliente quiere saber si la lista es algo. VocaciónmatchIt(empty()) significa que el cliente quiere saber si la lista está vacía. Viceversa paramatchIt(everyItem(equalToIgnoringCase("item"))) ymatchIt(hasItem("item")).

Mi objetivo aquí es tener unmejor matchIt() Método de firma posible. losMatcher<? super List<String>> Funciona bien para todos los escenarios anteriores. Sin embargo, creo que al cliente se le debe permitir agregarMatcher<Iterable<Object>> los emparejadores también (por ejemplomatchIt(everyItem(notNullValue()) tiene mucho sentido aquí, el cliente quiere saber si cada elemento de String de la lista no es nulo).

Sin embargo no puedo encontrar la firma correcta,matchIt(Matcher<? super List<? super String>>) no funciona paraeveryItem(notNullValue());

Yo uso Hamcrest 1.3.

EDIT 2:

Creo que he encontrado mi raíz malentendido.

loseveryItem(anything()) expresión devuelve un objeto de tipoMatcher<Iterable<Object>>. Así que puedo hacer fácilmenteMatcher<Iterable<Object>> m = everyItem(anything());

Sin embargo, lo que no entiendo es por qué no puedo hacer.Matcher<? super List<? super String>> m1 = m;. Parece queMatcher<Iterable<Object>> no esMatcher<? super List<? super String>> Pero no entiendo por qué.

Ni siquiera puedo hacerMatcher<? super List<?>> m1 = m;. Matcher<Iterable<Object>> no esMatcher<? super List<?>>? ¿Por qué?

Respuestas a la pregunta(2)

Su respuesta a la pregunta