我试图在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);
}
}
);
}
}
此代码由于此行final String s = adamTest.thing2(7).apply(i -> i.toString());
而无法编译。我认为我的类型边界有一些巧妙的错误,因为编译器似乎无法推断thing2(7).apply
的返回类型并报告Object
而不是String
我希望对
如何使泛型类型边界正确,以便编译器正确返回类型,即java.lang.String
推断 ?
答案 0 :(得分:8)
如前所述,这些陈述是从左到右评估的。
要强制编译器使用正确的类型,您只需将其写为
即可final String s = adamTest.<String>thing2(7).apply(String::valueOf);
编辑:根据评论,lambda表达式可以用方法引用替换(看起来更干净)。
答案 1 :(得分:5)
我不认为它可以在没有演员阵容的情况下修复(也许有人知道更好)。另一种方法是将您的陈述分为两行:
Function<Function<Integer, String>, String> thing2 = adamTest.thing2(7);
final String s = thing2.apply(i -> i.toString());
另请注意,thing2
可以简化:
private <R> Function<Function<Integer, R>, R> thing2(final Integer val) {
return fn1(i -> (op -> op.apply(val * i)));
}
答案 2 :(得分:-2)
您需要转到编译器的设置才能启用lambda表达式。这是intellij的一个例子。它已归档于&gt;项目结构,然后这个下拉列表。 希望这有帮助!
nvm,声誉不够。但我提供了详细信息。