Java Reference
In-Depth Information
Note that there is now a new way to have ambiguity in methods: you can have an overloaded method
that accepts both a Function<Integer,X> and an IntFunction<X> , such as in Figure 2-19. If you do this,
the compiler's error message will almost certainly confuse you. There are two error messages you could get
at this point, and which one depends on details of the lambda implementation. 9 Both of these messages
compete for least helpful error messages in Java 8, and they are "Cannot resolve method" and "Argument
cannot be applied to <lambda parameter> . " In this case, you will need to provide explicit typing, as we
discussed in “Lambdas with Explicit Typing.” If your explicit typing references the primitive type, you will get
the IntFunction variant; if your explicit typing references the boxed type, you will get the Function variant.
Listing 2-19. Ambiguous Method Types When Using Primitive Functional Interfaces
static void methodBeingCalled(Function<Integer, String> function) {}
static void methodBeingCalled(IntFunction<String> function) {}
public static void main(String[] args) {
// This will throw an exception
methodBeingCalled(i -> Integer.toString(i));
// This will not
methodBeingCalled((int i) -> Integer.toString(i));
Making Methods into Lambdas
Throughout this chapter, we have been constructing all of our lambdas explicitly: we have been constructing
our lambdas as anonymous functions. You can, however, also take any method call and turn it into a lambda.
When I say “any method call,” I mean it: static methods, instance methods, and constructors are all fair
game. This tiny little bit of syntactic glue makes transitioning from object-oriented code into functional code
very easy, and really provides a powerful way to get the best of both paradigms.
The structure that creates a lambda from a method is called a “method reference.” You create a method
reference much like you call a method, but use double colons ( :: ) instead of a period ( . ). I like to think
of the period as a single dot meaning, “let me call this method once,” whereas the colons are lots of dots
meaning, “let me call this method many times.” Once you create the method reference using the double
colons, you can work with the method reference just as you would work with an explicit lambda. The details
of making methods into lambda calls are handled in each of the subsections below.
Making Static Methods into Lambdas
The simplest case is turning a static method into a lambda. To do this, you will simply follow the formula
we laid out above: take the method call, and replace the period with a colon. The compiler will look into the
signature of that method and perform type inference, constructing the appropriate interface implementation
for you. Listing 2-20 shows static alternatives to a couple of the lambdas that we saw in 2-18: note that the
compiler successfully discovers that we want an IntFunction<String> , not a Function<Integer,String> ,
and provides the appropriate type. If the target type signature is ambiguous, such as in Listing 2-19, then you
have to get an explicit type signature in place. There are two ways to do this: either use an explicit lambda
with explicit typing to resolve it, or assign the method reference to a variable with the desired type and then
pass the variable in. As of Java 8, there is no way to do an inline cast operation on a method reference.
9 Namely, an explicit lambda versus a method reference. For information on method references, see the next section.
Search WWH ::

Custom Search