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?

+2

“优化”是什么意思? 'Function'和'DoubleToIntFunction'都是接口 - 没有什么可以优化的。 –

+0

我的意思是,那里会出现autofoxing for'f1.apply(d);'(double to Double)还是编译器会隐式地将f1的类型转换为DoubleFunction 或DoubleToIntFunction? – AmeyaKetkar

+1

编译器('javac')将不会执行任何操作,JIT可能会将它们编译到相同的本机代码中,具体取决于使用情况。 – Kayaman

我不明白它是怎么可能的,上面的lambda允许空值,而下面的lambda允许空值。 编译器将不得不做大量的静态代码分析,以查看是否可以将null传递给函数以优化它。

f1.apply(null); //works! 
f2.applyAsInt(null); //won't compile! 

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

不知道这是否仍然可行..由于可能性的总数以及可能发生此类优化的地方,这会为javac总编译时间增加大量时间。

+1

我不明白未来会发生这种情况,因为这样做会从根本上打破向后兼容。签名'Function '不仅意味着允许'null'的引用类型,而且还包括赋值兼容性。 '功能',它可以与不适合值类型的代码一起使用。 – Holger

+0

@Holger优点!张贴后,我有同样的疑虑向后兼容性。关于'的部分?扩展数字'可以很容易地在编译时检测到,并且在这种情况下根本不优化,我认为... – Eugene

Java编译器(javac)不执行这种类型的优化。实际上,如Optimization by Java Compiler所示,它只执行少量优化,以便将所有可用信息提供给JIT编译器。

所以,如果你声明一些lambda为Function<Double,Integer>,那么字节码将代表它 - 原型为Function。现在,根据该部分代码的上下文和执行负载,JIT编译器可能能够内联lambda(或其他实现方式),并生成非常相似或甚至完全相同的机器代码与DoubleToIntFunction版本产生。

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