Java Reference
In-Depth Information
Figure 2-2. The Predicate interface diagram, generating a boolean from an Object
Let's look at another, slightly more complex functional interface example: the
BinaryOper-
ator
interface, which is shown in
Example 2-13
.
This interface takes two arguments and re-
turns a value, all of which are the same type. In the code example we've used, this type is
Long
.
Example 2-13. A more complex type inference example
BinaryOperator
<
Long
>
addLongs
= (
x
,
y
) ->
x
+
y
;
The inference is smart, but if it doesn't have enough information, it won't be able to make
the right decision. In these cases, instead of making a wild guess it'll just stop what it's doing
and ask for help in the form of a compile error. For example, if we remove some of the type
information from the previous example, we get the code in
Example 2-14
.
Example 2-14. Code doesn't compile due to missing generics
BinaryOperator add
= (
x
,
y
) ->
x
+
y
;
This code results in the following error message:
Operator '+' cannot be applied to java.lang.Object, java.lang.Object.
That looks messy: what is going on here? Remember that
BinaryOperator
was a functional
interface that had a generic argument. The argument is used as the type of both arguments,
x
and
y
, and also for its return type. In our code example, we didn't give any generics to our
add
variable. It's the very definition of a
raw
type. Consequently, our compiler thinks that its
arguments and return values are all instances of
java.lang.Object
.
We will return to the topic of type inference and its interaction with method overloading in
Overload Resolution
,
but there's no need to understand more detail until then.