Reputation: 49
I've encountered the following code in a Java project, and I'm not sure what to make of it:
public Function<CustomEnum,String> foo(SomeObject someObject) {
return ((Function<CustomEnum,String>) (someObject::toString)).andThen(r -> someObject::getSomethingWithEnumParameter);
}
I don't really understand how you can cast something to a Functional Interface. What does that even mean?
Isn't the resulting type of the return value going to be whatever value someObject.
Isn't Function<CustomEnum, String>
defining an anonymous function that takes a type CustomEnum
and returns a String
?
I've read the java doc for Function<T,R>
, and to be honest, this doesn't make much more sense than before I read the document.
This is what I believe is happening.
foo is returning an anonymous function that is applied to some CustomEnum
to return a String
the anonymous function inside of foo (which is somehow cast onto someObject::toString
, which I don't understand) is applied to the CustomEnum
that will be passed from the initial call of foo(someObject).apply(customEnum)
.
The andThen
will take the resulting String from the anonymous function inside of foo (which was cast somehow I still don't understand), and then return the value of someObject::getSomethingWithEnumParameter
. Why isn't the return type just the type of someObject::getSomethingWithEnumParameter
, which we'll say is a Map<R,T>
, for sake of discussion.
If anyone could help me understand this flow, I would greatly appreciate it.
Upvotes: 0
Views: 1144
Reputation: 9408
In an ideal world this would work:
public Function<CustomEnum,String> foo(SomeObject someObject) {
return (someObject::toString).andThen(...);
}
However Java needs an interface type in order to implicitly create an interface instance from the method reference., hence the explicit cast is required to cast to the Function interface type.
Once you have an instance of Function then you can call any method on it as per normal, in this case the andThen
method which composes it with another function object to form a new function.
Breaking it down:
someObject::toString
is a method reference with implied type Function<CustomEnum, String>
. I.e. toString
is a method on SomeObject
which takes a parameter of type CustomEnum
and returns a String
.
r -> someObject::getSomethingWithEnumParameter
has the wrong type though - it's a function which returns a function. If you get rid of the "r ->
" part then it is valid, as long as someObject::getSomethingWithEnumParameter
is a method on SomeObject
that takes a String
and returns a String
. Alternatively the return type of foo
would need to change to Function<CustomEnum, Function<String, String>>
.
If you combine those two with andThen
then you have a Function
which takes a CustomEnum
and returns a String
, as pr the return type of foo
.
Upvotes: 2