Paul, I'm sorry, I think I'm missing a big concept here, but I still don't get it. I think the fact that I commented out getList() call from printNames just proves my point, not disproves it.
So I left printNames(String s) completely empty. If I remove static keyword - it doesn't compile (with the error in second example above). If I add static keyword - it does. How can it be said, then, that compilation error is NOT due to non-static reference from a static context?
The compiler doesn't even see the method unless it is made static.
The necessity to comment out getList () was just a waterfall effect - when getNames became static - then it in turn started making a non-static reference to getList. I added System.out.println(getList()) back to static printNames and tried to recompile, and got the following error:
error: non-static method getList() cannot be referenced from a static context
Now there is a more direct message.
I agree with your general statement, that
It is possible to reference a non-static method from a static method as long as you are invoking the non-static method on a valid object reference.
After all, the static main method is successfully calling getLest() on the non-static TestClass reference it just created. However, I do not think that forEach does something similar, in this case anyway. If it had, then indeed non-static printNames could have been invoked on an element. And the presence or absence of any method body in printNames would have been irrelevant - after all, it would just be a method call. But the compiler is not allowing a non-static call to printNames, so method reference to a non-static method is not allowed in a static context, even though it will be applied to a valid non-static object reference returned by forEach.
I hope that wasn't too confusing. Thank you for reading and working through this with me!