Generics hell: hamcrest matcher jako parametr metody

Zróbmy więc listę łańcuchów i funkcję, która pobiera matcher Hamcresta i zwraca wynikmatches() metoda dostarczonego matchera:

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

Jak na razie dobrze. Teraz mogę łatwo zadzwonić:

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

... ponieważ wszystkie te fabryczne metody statyczne wytwarzają urządzenie dopasowujące do podpisu metodyMatcher<? super List<String>>.

Uważam jednak, że urządzenie akceptujące obiekty Iterable powinno zostać zaakceptowane przezmatchIt()&nbsp;metoda:

matchIt(everyItem(anything()));

Więc naiwnie zmieniłemmatchIt()&nbsp;podpis metody:

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

Ale to w ogóle nie działa. Nie tylko nie akceptujeeveryItem(anything()), nie akceptuje nawet poprawnego poprzednioeveryItem(equalToIgnoringCase("item"))&nbsp;mówiąc (wersja kompilatora 1.7.0_05):

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

Co? Więc co tu jest nie tak? Czy to jestmatchIt()&nbsp;podpis metody lub jesteveryItem()&nbsp;Źle zaprojektowany podpis Hamcresta? Czy może po prostu nie można naprawić systemu generycznego Java? Wielkie dzięki za komentarze!

EDYTUJ @rlegendi Moim zamiarem jest zapewnienie interfejsu dla klienta do dodawania i wykonywania predykatów dotyczących listy. To jestmatchIt()&nbsp;metoda. PowołaniematchIt(anything())&nbsp;ma sens w tym scenariuszu, klient chce wiedzieć, czy lista jest czymś. PowołaniematchIt(empty())&nbsp;oznacza, że ​​klient chce wiedzieć, czy lista jest pusta. Odwrotnie dlamatchIt(everyItem(equalToIgnoringCase("item")))&nbsp;imatchIt(hasItem("item")).

Moim celem jest posiadanieNajlepiej matchIt()&nbsp;możliwy podpis metody. TheMatcher<? super List<String>>&nbsp;działa dobrze dla wszystkich poprzednich scenariuszy. Uważam jednak, że klient powinien mieć możliwość dodaniaMatcher<Iterable<Object>>&nbsp;również zapałki (na przykładmatchIt(everyItem(notNullValue())&nbsp;ma tu sens, klient chce wiedzieć, czy każdy element String na liście nie jest pusty).

Jednak nie mogę znaleźć właściwego podpisu,matchIt(Matcher<? super List<? super String>>)&nbsp;nie działa dlaeveryItem(notNullValue());

Używam Hamcrest 1.3.

EDYCJA 2:

Wierzę, że znalazłem swoje nieporozumienie.

TheeveryItem(anything())&nbsp;wyrażenie zwraca obiekt typuMatcher<Iterable<Object>>. Więc mogę zrobić łatwoMatcher<Iterable<Object>> m = everyItem(anything());

Jednak nie rozumiem, dlaczego nie mogę tego zrobićMatcher<? super List<? super String>> m1 = m;. Wygląda na to żeMatcher<Iterable<Object>>&nbsp;nie jestMatcher<? super List<? super String>>&nbsp;ale nie rozumiem dlaczego.

Nawet nie mogę tego zrobićMatcher<? super List<?>> m1 = m;. Matcher<Iterable<Object>>&nbsp;nie jestMatcher<? super List<?>>? Czemu?