0
Function<Double,Integer> f1=(d)-> {
        if(d>5)
            return 0;
        return 1;
    };
DoubleToIntFunction f2=(d)-> {
        if(d>5)
            return 1;
        return 0;
    };
double d=5.0;
f1.apply(d);
f2.applyAsInt(d);

将 f1 优化为 DoubleToIntFunction(类似于 f2)。

4

3 回答 3

6

我不明白它是怎么做到的,上面的 lambda 允许空值,而下面的不允许。编译器必须进行大量静态代码分析,以查看是否可以将 null 传递给 Function 以对其进行优化。

f1.apply(null); //works!
f2.applyAsInt(null); //won't compile!
于 2017-04-17T19:41:18.573 回答
3

假设有两件事,据我所知,这可能会在未来发生。1) Double 和 Integer 可以是value types; 因此永远不会为空,并且 2) AOT javac 编译器将到位。

不确定这是否仍然可行。由于可能发生此类优化的可能性和位置的总数,这将增加 javac 总编译时间的大量时间。

于 2017-04-17T20:00:30.773 回答
3

Java 编译器 (javac) 不执行此类优化。事实上,正如Java Compiler 优化中所指出的,它只执行很少的优化,以便将所有可用信息提供给 JIT 编译器。

因此,如果您将某个 lambda 声明为Function<Double,Integer>,则字节码将这样表示它——好吧,以其原始类型Function.

现在,根据该部分代码的上下文和执行负载,JIT 编译器可能能够内联 lambda(或该 lambda 的其他实现Function)并生成与其使用版本生成的非常相似甚至相同的机器代码DoubleToIntFunction

请注意,在这种情况下,类型信息会完全消失。它不会用另一个代替。

于 2017-04-17T22:46:31.763 回答