Java 8 method references are super useful in expressions like these:
Comparator.comparing is a generic method. Here’s its signature:
comparing(), the first parameter (
keyExtractor) can be provided
in one of three ways:
- a method reference (as shown in our example)
- a reference to a
- a lambda expression
Which alternatives you may use depends on the situation. Depending on the
situation, the compiler will either use the expected return
comparing()) to determine the type of
keyExtractor, or it will use the type of the first parameter to determine the
return type. In the latter case either a method reference or a reference to a
Function object is required, since a lambda, in general might not carry
sufficient type information.
Method references are also often seen when
map()ing, either over streams,
On the second line, though, the compiler knows the type of
speaker, so it
knows the type of the
map() parameter. Here’s
U is known from the declaration of
speaker. The type information carried
by the method reference
Speaker::speak isn’t actually needed in this case.
Not only is it not needed, it represents a minor but annoying maintenance trap.
By explicitly specifying the type of
speaker and also explicitly specifying
the type of the first argument to
map() we’ve set them in opposition when they
needn’t be. Sure, the compiler will tell if some future code change causes them
to be incompatible (say if the
speak() method moves to another class or
interface), but wouldn’t it be better if the
map() expression was decoupled
entirely from the name of that class or interface?
Since the compiler doesn’t need that extra type information, and since we pay a
price in maintainability by including the extra type information, it’d be nice
if we had another way to specify the method to
How about a trivial lambda:
This code is shorter
Speaker::speak. It also has the
advantage of not tightly coupling the expression to the interface name.
By efficiently leveraging type inference, we’ve improved our code.
Here’s a little Github repo with the Java code: Lambda vs Method Reference on Bill’s Github
In Java 8, functional interfaces, method references, and lambda expressions provide wonderful new opportunities to create higher-order functions. In some situations, though, a method reference, by saying too much, presents a little maintenance trap that can be avoided via a trivial lambda expression.