method references: type inference, toString()

Paul Holser pholser at
Tue Feb 21 14:31:29 PST 2012

Hi lambda-dev,

Using JDK 8 Developer Preview with lambda support
Guava 11.0, Hamcrest 1.3.RC2, and JUnit 4.10 (sans Hamcrest classes).

org.hamcrest.Matcher is not a SAM type, whereas is.


==== begin ====
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;

interface Foo {
    boolean isBar();

abstract class PredicateMatcher<T> extends TypeSafeMatcher<T> {
    protected final Predicate<? super T> predicate;

    private PredicateMatcher(Predicate<? super T> predicate) {
        this.predicate = predicate;

    @Override public final boolean matchesSafely(T target) {
        return predicate.apply(target);

    public static <U> PredicateMatcher<U> matches(Predicate<? super U>
predicate) {
        return new PredicateMatcher<U>(predicate) {
            @Override public void describeTo(Description description) {
                description.appendText("a value acceptable to predicate ");

class BarredUpFoo implements Foo {
    @Override public boolean isBar() {
        return true;

class BarredUpFooTest {
    @Test public void bar() {
       assertThat(new BarredUpFoo(), PredicateMatcher.matches(Foo::isBar));

public class Main {
    public static void main(String... args) {
        Predicate<Foo> bar = Foo::isBar;
==== end ====


==== begin console output ==== error: no suitable method found for matches(member reference)
       assertThat(new BarredUpFoo(), PredicateMatcher.matches(Foo::isBar));
    method PredicateMatcher.<U>matches(Predicate<? super U>) is not applicable
      (cyclic inference - cannot infer target type for given lambda/method refer
ence expression)
    method TypeSafeMatcher.matches(Object) is not applicable
      (actual argument member reference cannot be converted to Object by method
invocation conversion
        (the target type of a lambda conversion must be an interface))
  where U is a type-variable:
    U extends Object declared in method <U>matches(Predicate<? super U>)
1 error
==== end console output ====

Couple of questions:

1) Should the usage of Foo::isBar as the predicate fed to
PredicateMatcher.matches() compile successfully? I'm hoping not to
have to perform the SAM conversion by hand:

    Predicate<Foo> bar = Foo::isBar;
    assertThat(new BarredUpFoo(), PredicateMatcher.matches(bar);

In Main.main(), I perform that SAM conversion by hand, as you can see
-- otherwise, it won't know to choose PrintStream.println(Object), it
says "(actual argument member reference cannot be converted to Object
by method invocation conversion)".

2) Wondering if it wouldn't be too much trouble to have method
references respond to toString() with something like "Foo::isBar" or
"method isBar on class Foo", instead of, e.g. "Main$1 at a30a4e". It'd
make the output of PredicateMatcher.matches() really slick.

Thanks for the help, and the great work thus far!

Paul Holser

More information about the lambda-dev mailing list