Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast java.util.function.Function to Interface

Tags:

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?

like image 263
tomaj Avatar asked Aug 27 '15 07:08

tomaj


1 Answers

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; 
like image 102
Hoopje Avatar answered Oct 15 '22 01:10

Hoopje