java编译器是否将Function 转换为DoubleToIntFunction?
问题描述:
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)。java编译器是否将Function <Double,Integer>转换为DoubleToIntFunction?
答
我不明白它是怎么可能的,上面的lambda允许空值,而下面的lambda允许空值。 编译器将不得不做大量的静态代码分析,以查看是否可以将null传递给函数以优化它。
f1.apply(null); //works!
f2.applyAsInt(null); //won't compile!
答
假设有两件事,就我所知,这可能发生在将来。 1)Double和Integer可以是value types
;因此永远不会为空,并且2)将会有一个AOT javac编译器。
不知道这是否仍然可行..由于可能性的总数以及可能发生此类优化的地方,这会为javac总编译时间增加大量时间。
答
Java编译器(javac)不执行这种类型的优化。实际上,如Optimization by Java Compiler所示,它只执行少量优化,以便将所有可用信息提供给JIT编译器。
所以,如果你声明一些lambda为Function<Double,Integer>
,那么字节码将代表它 - 原型为Function
。现在,根据该部分代码的上下文和执行负载,JIT编译器可能能够内联lambda(或其他实现方式),并生成非常相似或甚至完全相同的机器代码与DoubleToIntFunction
版本产生。
请注意,在这种情况下,类型信息会完全消失。它不会取代另一个。
“优化”是什么意思? 'Function'和'DoubleToIntFunction'都是接口 - 没有什么可以优化的。 –
我的意思是,那里会出现autofoxing for'f1.apply(d);'(double to Double)还是编译器会隐式地将f1的类型转换为DoubleFunction或DoubleToIntFunction? –
AmeyaKetkar
编译器('javac')将不会执行任何操作,JIT可能会将它们编译到相同的本机代码中,具体取决于使用情况。 – Kayaman