The 'methods' you talk about are called lambdas and they are a powerful tool, because they are more than they initially seem. On the first look a lambda is nothing but behavior wrapped in slim syntax. But actually a lambda can do much more.
For example, lambdas 'capture' values they use from their respective scope at creation time:
...
final MyType t = someObject;
Runnable runner = () -> t.someMethod();
return runner;
...
...
runner.run();
This is actually a call to the someMethod
of the object someObject
. This means, that a lambda actually has a context at the position it is created, as opposed to where it is called.
But there is more: You can actually pass just a method (as you describe), if the method fits the specific signature of the expected interface:
List<String> myStrings = ...;
myStrings.forEach(System.out::println);
As you can see, you can actually link object-specific methods, not just static ones. Once again, you have passed context.
Now to the specific question: Why return a method-lambda from a method call?
Map<String, Consumer<String>> handlers = new HashMap<>();
...
public Consumer<String> getHandler(String key) {
Consumer<String> h = handlers.get(key);
if (h == null) {
return System.out::println;
}
return h;
}
Now you can link the handler you store somewhere central to another object, for which you define a behavior.