Example
In this (simplified) example I can create my MyInterface
-object by using a method reference to apply
, but casting directly doesn't work.
@Test public void testInterfaceCast(){ Function<String, Integer> func = Integer::parseInt; MyInterface legal = func::apply; // works MyInterface illegal = func; // error } public interface MyInterface extends Function<String, Integer>{}
The second assignment gives the compiler error:
incompatible types: Function<String,Integer> cannot be converted to MyInterface
The question
Can I do some Generics magic, to be able to cast a Function<T, R>
to an Interface?
The reason MyInterface illegal = func;
doesn't work, is because func
is declared as a variable of type Function<String,Integer>
, which is not a sub-type of MyInterface
.
The reason why MyInterface legal = func::apply;
works is the following. You might expect the type of fun::apply
to be Function<String,Integer>
as well, but this is not the case. The type of fun::apply
depends in part on what type the compiler expects. Since you use it in an assignment context, the compiler expects an expressen of type MyInterface
, and therefore in that context func::apply
is of type MyInterface
. It is for this reason, that method reference expression can only appear in a assignment contexts, invocation contexts and casting contexts (see the Java Language Specification).
Since Function<String,Integer>
is not a sub-type of MyInterface
, casting func
to a MyInterface
throws a ClassCastException
. Therefore, the clearest way to convert a Function<String,Integer>
to a MyInterface
is to use a method reference, as you already did:
MyInterface legal = func::apply;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With