Мэтт прав около <? super T>
в hasSomethingMatching()/hasSomethingWhich()
, чтобы заставить его работать:
Matcher<Container<String>> tmp = hasSomethingWhich(is("foo"));
assertThat(container, tmp);
необходима переменная tmp
, javac выведет только T == Stringв этом назначении, а не в произвольных выражениях.(или вы можете явно указать T как String при вызове метода).
Если затмение ослабляет правила вывода, то это противоречит спецификации языка.Давайте посмотрим в этом примере, почему это неуместно:
public static <T> Matcher<Container<T>>
hasSomethingWhich(final Matcher<? super T> matcher)
Этот метод по своей природе опасен.учитывая Match<Object>
, он может вернуть Matcher<Container<Foo>>
, где Foo
может быть чем угодно.Нет никакого способа узнать, что это за хрень T
, если только вызывающая сторона не предоставит T
явно, или компилятор не выведет T
из контекста.
Спецификация языка определяет правило вывода вприведенное выше утверждение присваивания, поскольку намерение разработчика абсолютно ясно, что T должно быть точно String
Сторонники большего количества правил вывода должны предоставить точный набор правил, который они хотят, доказать, что правила безопасны и надежны,и понятным для смертных.