Here, I am trying to pass lambda argument into local invocation of a method that accepts lambda argument:
package Desktop;
import java.util.function.*;
public class MyClass {
public static <T, U> U myMethod(Function<T, U> myParam) {
return otherMethod(myParam);
}
public static Long otherMethod(Function<String, Long> otherParam) {
return otherParam.accept("900");
}
public static void main(String[] args) {
System.out.println(myMethod(Long::valueOf));
}
}
I browsed for some help on sites and it shows that we can pass lambda (with generics) from one parameter into another:
public static <T, G> List<G> fromArrayToList(T[] a, Function<T, G> mapperFunction) {
return Arrays.stream(a).map(mapperFunction).collect(Collectors.toList());
}
/*
Signature for map() is like this:
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
*/
Now how to properly pass a lambda with generics from parameter method into another?
One problem is that there are two signatures of valueOf
. One takes a primitive long, the other takes a string.
There is no way for Java to know which one you mean.
You can manually specify by using a type witness:
System.out.println(MyClass.<String, Long>myMethod(Long::valueOf));
or, if you prefer, assign the method reference to a variable so that additional type information can be inferred from the variable.
Function<String, Long> func = FakeLong::valueOf;
System.out.println(MyClass.myMethod(func));
Another problem is here:
return otherMethod(myParam);
Fact is, otherMethod
specifically requires a function that takes a String and returns a long, while myParam
can be any function at all. There is a fundamental incompatibility here. Your design is wrong.