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

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推断由编译器?

See*_*ose 8

如前所述,这些陈述从左到右进行评估.

要强制编译器使用正确的类型,您只需将其编写为

final String s = adamTest.<String>thing2(7).apply(String::valueOf);
Run Code Online (Sandbox Code Playgroud)

编辑:根据注释,lambda表达式可以替换为方法引用(看起来更干净).


ass*_*ias 5

我不认为没有演员阵容可以修复(也许有人知道更好).另一种方法是将您的陈述分为两行:

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)