ada*_*ter 5 java generics lambda java-8
我试图在Java 8中的一些高阶函数中保留lambda表达式的返回类型的泛型类型信息.我已将实际代码简化为此测试用例.问题不是我期望代码完全按照我所期望的那样,而是我希望将泛型类型R推断为java.lang.String并通过函数调用进行传递.
import java.util.function.Function;
public class AdamTest {
public final static void main(final String args[]) {
final AdamTest adamTest = new AdamTest();
final String s = adamTest.thing2(7).apply(i -> i.toString());
System.out.println(s);
}
private <R> R fn1(final Function<Integer, R> op) {
return op.apply(10);
}
private <R> Function<Function<Integer, R>, R> thing2(final Integer val) {
return fn1(i -> new Function<Function<Integer, R>, R>() {
@Override
public R apply(Function<Integer, R> op) {
return op.apply(val * i);
}
}
);
}
}
Run Code Online (Sandbox Code Playgroud)
目前此代码由于此行而无法编译final String s = adamTest.thing2(7).apply(i -> i.toString());.我认为我的类型边界有一些巧妙的错误,因为编译器似乎无法推断返回类型thing2(7).apply和报告Object而不是String我希望的.
如何获得通用型边界正确,使正确的返回类型,即java.lang.String是推断由编译器?
如前所述,这些陈述从左到右进行评估.
要强制编译器使用正确的类型,您只需将其编写为
final String s = adamTest.<String>thing2(7).apply(String::valueOf);
Run Code Online (Sandbox Code Playgroud)
编辑:根据注释,lambda表达式可以替换为方法引用(看起来更干净).
我不认为没有演员阵容可以修复(也许有人知道更好).另一种方法是将您的陈述分为两行:
Function<Function<Integer, String>, String> thing2 = adamTest.thing2(7);
final String s = thing2.apply(i -> i.toString());
Run Code Online (Sandbox Code Playgroud)
另请注意,thing2可以简化:
private <R> Function<Function<Integer, R>, R> thing2(final Integer val) {
return fn1(i -> (op -> op.apply(val * i)));
}
Run Code Online (Sandbox Code Playgroud)