Not really, this data is not kept by the compiler. You would either create a separate class for lambda:
interface StringFunc extends Function<String, String> {}
And then you can get StringFunc super interface to get Function<String, String>.
Or just use classes instead of lambdas:
printIt(new Function<String, String>() {
@Override
public String apply(String s) {
return s;
}
});
Lambdas also generate synthetic method in the class they were declared in:
Function<String, String> x = (String a) -> a;
printIt(x);
for (Method declaredMethod : Test.class.getDeclaredMethods()) {
if (declaredMethod.isSynthetic()) {
System.out.println(declaredMethod);
}
}
}
will print
public java.lang.Object org.gotofinal.Test$$Lambda$14/0x0000000800066840.apply(java.lang.Object)
private static java.lang.String org.gotofinal.Test.lambda$main$0(java.lang.String)
But I don't see option to get declaration class of lambda (but can be extracted from class name) and how to match method with a lambda + it's implementation specific so might not work on every version of jvm. Also this method will include types of local variables passed to lambda:
int dd = "dddd".length() + args.length;
Function<String, String> x = (String a) -> a + dd;
will print:
private static java.lang.String org.gotofinal.Test.lambda$main$0(int,java.lang.String)
So probably your best bet is to just pass type as separate argument:
public <F, T> Whatever method(Class<F> typeF, Class<T> typeT, Function<F, T> func)