Based on http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html , we know that method references are similar to the following lambdas
method reference ==> lambda ------------------------------------------------------------------------------------ object::method ==> (Foo f, Bar b, Baz z) -> object.method(f,b,z) SomeClass::staticMethod ==> (Foo f, Bar b, Baz z) -> SomeClass.staticMethod(f,b,z) SomeClass::instanceMethod ==> (Foo f, Bar b, Baz z) -> f.instanceMethod(b,z) SomeClass::new ==> (Foo f, Bar b, Baz z) -> new SomeClass(f,b,z)
So your code
userList.forEach(User::printName);
can be rewritten as
userList.forEach((User u) -> u.printName()); // works
because it means that in the accept Consumer method that this lambdas "implements", you will call printName() for each User passed to this method.
But in case
userList.forEach(u1::printName);
this code represents the following lambda
userList.forEach((User u) -> u1.printName(u)); // compile error // ^^^ // method doesn't accept User argument
so you are trying to call printName from the instance contained in the u1 link and pass each User from the list as an argument to the method, but as you can see
public void printName()
cannot accept a User instance as an argument, so you see a compile-time error.