亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

一個lambda表達式是否每次執行時都在堆上創建一個對象?

一個lambda表達式是否每次執行時都在堆上創建一個對象?

森欄 2019-06-20 15:25:07
一個lambda表達式是否每次執行時都在堆上創建一個對象?當我使用Java 8的新語法糖遍歷集合時,如myStream.forEach(item -> {   // do something useful});這不等同于下面的“舊語法”片段嗎?myStream.forEach(new Consumer<Item>() {   @Override   public void accept(Item item) {     // do something useful   }});這是否意味著一個新的匿名者Consumer對象是在堆上每次迭代集合時創建的?這需要多少堆空間?它對性能有什么影響?這是否意味著我應該在大型多級數據結構上迭代時使用舊的循環樣式?
查看完整描述

3 回答

?
蕪湖不蕪

TA貢獻1796條經驗 獲得超7個贊

它是等同的,但不是完全相同的。簡單地說,如果lambda表達式沒有捕獲值,那么它將是在每次調用中重復使用的單例。

未精確指定行為。JVM有很大的自由如何實現它。目前,Oracle的JVM為每個lambda表達式創建(至少)一個實例(即在不同的相同表達式之間不共享實例),而是為所有不捕獲值的表達式創建單個實例。

你可以讀這個答案更多細節。在那里,我不僅給出了更詳細的描述,而且還測試了代碼來觀察當前的行為。


Java語言規范第一章介紹了這一點15.27.4Lambda表達式的運行時計算

摘要:

這些規則旨在為Java編程語言的實現提供靈活性,因為:

  • 不需要為每個評估分配一個新對象。

  • 由不同的lambda表達式生成的對象不需要屬于不同的類(例如,如果主體是相同的)。

  • 由計算產生的每個對象不一定屬于同一個類(例如,捕獲的局部變量可能是內聯的)。

  • 如果“現有實例”可用,則不需要在以前的lambda計算中創建它(例如,它可能是在封閉類初始化期間分配的)。


查看完整回答
反對 回復 2019-06-20
?
侃侃無極

TA貢獻2051條經驗 獲得超10個贊

將一個新實例傳遞給forEach方法。每次這樣做,您都會創建一個新對象,而不是為每個循環迭代創建一個對象。迭代在內部完成forEach方法使用相同的“回調”對象實例,直到循環完成為止。

因此,循環使用的內存不取決于集合的大小。

這不等同于“舊語法”片段嗎?

是。它在一個很低的水平上有微小的差異,但我認為你不應該關心它們。Lamba表達式使用InvokeDynamic特性而不是匿名類。


查看完整回答
反對 回復 2019-06-20
  • 3 回答
  • 0 關注
  • 1659 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號