Итак, у нас есть список строк и функция, которая принимает сопоставитель Hamcrest и возвращает результат метода matches()
предоставленного сопоставителя:
public boolean matchIt(final Matcher<? super List<String>> matcher) {
final List<String> lst = obtainListFromSomewhere();
return matcher.matches(lst);
}
Все идет нормально. Теперь я легко могу позвонить:
matchIt(empty());
matchIt(anything());
matchIt(hasItem("item"));
matchIt(everyItem(equalToIgnoringCase("item")));
... поскольку все эти фабричные статические методы производят сопоставление, которое соответствует сигнатуре метода Matcher<? super List<String>>
.
Однако я считаю, что сопоставитель, который принимает Iterable объектов, также должен приниматься методом matchIt()
:
matchIt(everyItem(anything()));
Поэтому я наивно изменил подпись метода matchIt()
:
public boolean matchIt(final Matcher<? super List<? super String>> matcher);
Но это совсем не работает. Он не только не принимает everyItem(anything())
, но даже не принимает ранее правильное everyItem(equalToIgnoringCase("item"))
высказывание (версия компилятора 1.7.0_05):
actual argument Matcher<Iterable<String>> cannot be converted to Matcher<? super List<? super String>> by method invocation conversion
Что за? Так что здесь не так? Это сигнатура метода matchIt()
или сигнатура everyItem()
Hamcrest разработана неправильно? Или это просто не подлежит ремонту система дженериков Java? Большое спасибо за комментарии!
ИЗМЕНИТЬ @rlegendi, я намерен предоставить клиенту интерфейс для добавления и выполнения предикатов для списка. Это matchIt()
метод. Вызов matchIt(anything())
имеет смысл в этом сценарии, поскольку клиент хочет знать, есть ли в списке что-нибудь. Вызов matchIt(empty())
означает, что клиент хочет узнать, пуст ли список. И наоборот для matchIt(everyItem(equalToIgnoringCase("item")))
и matchIt(hasItem("item"))
.
Моя цель здесь - получить лучшую matchIt()
сигнатуру метода. Matcher<? super List<String>>
отлично работает для всех предыдущих сценариев. Однако я считаю, что клиенту должно быть разрешено добавлять Matcher<Iterable<Object>>
сопоставителей (например, matchIt(everyItem(notNullValue())
имеет здесь смысл, клиент хочет знать, не является ли каждый строковый элемент списка нулевым).
Однако я не могу найти нужную подпись, matchIt(Matcher<? super List<? super String>>)
не работает для everyItem(notNullValue());
Пользуюсь Hamcrest 1.3.
РЕДАКТИРОВАТЬ 2:
Я считаю, что нашел свое коренное недоразумение.
Выражение everyItem(anything())
возвращает объект типа Matcher<Iterable<Object>>
. Так что я могу легко Matcher<Iterable<Object>> m = everyItem(anything());
Однако я не понимаю, почему я не могу делать Matcher<? super List<? super String>> m1 = m;
. Кажется, что Matcher<Iterable<Object>>
не Matcher<? super List<? super String>>
, но я не понимаю, почему.
Я даже не умею Matcher<? super List<?>> m1 = m;
. Matcher<Iterable<Object>>
это не Matcher<? super List<?>>
? Почему?
Matcher<?>
не решит все ваши проблемы? Кстати, не могли бы вы рассказать немного больше о том, какой матчер вы хотели бы создать? Вы хотите сопоставить довольно много вещей (Object
,Collection<? extends Object>
,Iterable<? super String>
и т. Д.), Что немного странно для меня, возможно, более подробное описание может помочь нам лучше понять вашу проблему. - person rlegendi   schedule 22.10.2012matcher
таких операций не было. - person rlegendi   schedule 22.10.2012List<List<? super String>>
stackoverflow.com / questions / 13289847 / - person Arend v. Reinersdorff   schedule 13.11.2012