2017-04-17 57 views
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)。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

回答

6

我不明白它是怎麼可能的,上面的lambda允許空值,而下面的lambda允許空值。 編譯器將不得不做大量的靜態代碼分析,以查看是否可以將null傳遞給函數以優化它。

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

假設有兩件事,就我所知,這可能發生在將來。 1)Double和Integer可以是value types;因此永遠不會爲空,並且2)將會有一個AOT javac編譯器。

不知道這是否仍然可行..由於可能性的總數以及可能發生此類優化的地方,這會爲javac總編譯時間增加大量時間。

+1

我不明白未來會發生這種情況,因爲這樣做會從根本上打破向後兼容。簽名'Function '不僅意味着允許'null'的引用類型,而且還包括賦值兼容性。 '功能<雙人,?擴展Number>',它可以與不適合值類型的代碼一起使用。 – Holger

+0

@Holger優點!張貼後,我有同樣的疑慮向後兼容性。關於'的部分?擴展數字'可以很容易地在編譯時檢測到,並且在這種情況下根本不優化,我認爲... – Eugene

3

Java編譯器(javac)不執行這種類型的優化。實際上,如Optimization by Java Compiler所示,它只執行少量優化,以便將所有可用信息提供給JIT編譯器。

所以,如果你聲明一些lambda爲Function<Double,Integer>,那麼字節碼將代表它 - 原型爲Function。現在,根據該部分代碼的上下文和執行負載,JIT編譯器可能能夠內聯lambda(或其他實現方式),並生成非常相似或甚至完全相同的機器代碼與DoubleToIntFunction版本產生。

請注意,在這種情況下,類型信息會完全消失。它不會取代另一個。

相關問題