为什么在映射到Callable <T>时我需要明确地给出类型参数?

ski*_*iwi 7 java generics lambda type-inference java-8

当我试图回答一个不同的问题时,我发现只有在我明确给出类型参数时我的代码才会编译(无论代码计算的是什么都没有意义,我知道):

public Double calculateResult(int value) {
    return 0.0d;
}

private void init2() {
    List<Callable<Double>> list = IntStream.range(1, 99)
            .<Callable<Double>>mapToObj(value -> (() -> calculateResult(value)))
            .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

<Callable<Double>>从中删除类型参数时mapToObj,它不会编译,并给出错误

不能自己推断出类型变量

如果我改变它使用a Supplier<Double>或a ,它既不能推断出论据DoubleSupplier.

为什么它不能推断类型参数?

更新,我正在使用Netbeans 8.0进行编译,尚未使用javac编译器进行检查.

Sim*_*erg 5

这是我对正在发生的事情的理解.

问题是您希望编译器使用预期的赋值类型,在这种情况下List<Callable<Double>>,推断类型参数.但是,.mapToObj它不是链中的最后一个语句,它不会返回List.

下面的代码可以工作,因为这里编译器可以将.mapToObj调用的结果与您声明的返回类型相匹配,因此它可以推断出流的类型参数.

Stream<Callable<Double>> temporaryVariable = IntStream.range(1, 99)
    .mapToObj(value -> (() -> calculateResult(value)));
List<Callable<Double>> list = temporaryVariable.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

因为它不是链中的最后一个语句,如果我是一个编译器,我真的不想通过所有可能的值Stream<?>(基本上是返回类型.mapToObj)找到一个与下一个调用匹配的调用.回来List<Callable<Double>>.