Reputation: 97
I cannot figure out why this code don't compile :
package Desktop;
import java.util.function.*;
public class MyClass {
public static <T, U> Long myMethod( Function<T, U> methodParam ) {
return methodParam.apply("Today is happy day!");
}
public static void main(String[] args) {
System.out.println( <String, Long>myMethod( Long::valueOf ) );
}
}
So i receive this on console:
..\Desktop\MyClass.java:15: error: illegal start of expression
System.out.println( <String, Long>myMethod( Long::valueOf ) );
^
..\Desktop\MyClass.java:15: error: ';' expected
System.out.println( <String, Long>myMethod( Long::valueOf ) );
^
2 errors
I am expecting to use generics to include type for the lambda on method parameter.
Upvotes: 0
Views: 1290
Reputation: 2245
The reason is that Long.valueOf()
takes only either String
or long
. From the type parameter T
, the compiler concludes that the Function
takes Object
, it will not allow it since there is no method as Long.valueOf( Object )
.
You may have to change myMethod()
to this signature:
public static <T, U> Long myMethod( Function<String, Long> methodParam ) { //Both type parameters are explicit
return methodParam.apply("Today is happy day!");
}
Or this, which may throw NumberFormatException
:
public static <T, U> Long myMethod( Function<String, U> methodParam ){ //Input type parameter is explicit
return (Long) methodParam.apply( "Today is happy day!" );
}
Upvotes: 1
Reputation: 55
As Eran's answer suggests, you have 2 problems: In the definition of myMethod and in the call of the method.
1) You declare methodParam as a function with input type T and output type U. And then in myMethod you treat it as if T was String and U was Long. This is only how you want to call the method but the compiler does not know anything about T and U at this point. Erans solution for myMethod works as myMethod returns a value of type U (instead of Long) and receives a parameter of type T instead of calling apply() with a string.
2) The call of myMethod() in the main method: either as in Erans example the type parameters are implicitly given by your parameters. Otherwise, if you need to express them explicitly for some reason, @ernest_k showed the solution (also found here).
Upvotes: 1
Reputation: 393811
It should be:
public static <T, U> U myMethod(Function<T, U> methodParam, T t) {
return methodParam.apply(t);
}
public static void main(String[] args) {
System.out.println(myMethod(Long::valueOf, "Today is happy day!") );
}
myMethod
accepts a Function
with generic parameters, so you can't always call its apply
method with a String
argument and expect it to return a Long
.
Instead, you can pass to it the String
argument, and change its return type to U
.
Of course, this code will throw a NumberFormatException
, since you can't convert that String
to a Long
.
Upvotes: 5