Java 8 - 使用lambdas推断泛型返回类型

时间:2015-03-06 11:48:57

标签: 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);
                }
            }
        );
    }
}

此代码由于此行final String s = adamTest.thing2(7).apply(i -> i.toString());而无法编译。我认为我的类型边界有一些巧妙的错误,因为编译器似乎无法推断thing2(7).apply的返回类型并报告Object而不是String我希望对

如何使泛型类型边界正确,以便编译器正确返回类型,即java.lang.String 推断

3 个答案:

答案 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,声誉不够。但我提供了详细信息。