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