總是返回集合/對象字段的副本會是開銷嗎?在可變對象的getter中進行深度複製
1
A
回答
1
確實存在開銷,但已經有一些框架類可以做到這一點。這也在有效的Java書中描述。
記住:
「類應該是一成不變的,除非有一個很好的理由讓他們可變....如果一個類不能進行能不變,限制了它的可變性儘可能地。」
當你想創建一成不變的類比你可以使用這樣的框架:http://immutables.github.io
有關示例檢查這個Oracle documentation
0
所有處理有成本。創建對象並初始化它們具有CPU和內存成本。 框架可以爲你做什麼,這是可能的,但如果你以一種方便的方式做到這一點,它不會降低這個成本。相反,如果手動執行,則兩個對象之間的映射屬性的性能會更好。 如果你注意表現,也許你應該研究是否可以避免深層複製。
2
顯然,是的,這將是一個開銷...與返回參考或淺拷貝相比。
但這不是重點。真正的意義在於開銷是否有保證/必要,以及是否可以通過使用其他數據結構/設計/技術來避免。這些問題的答案取決於上下文。
下面是一些例證:
- 如果目標對象的吸氣劑返回一個不可變的對象,副本是不必要的。例如,任何返回
String
的getter。 - 如果目標對象獲取器返回的對象不是目標對象抽象的一部分,則副本不受歡迎。示例
list.get(int)
,Iterator.next()
。 - 如果目標對象的吸氣劑返回一個可變對象(或陣列)AND返回的對象是該對象的內部狀態的一部分AND目標不一定信任呼叫者,則吸氣劑要麼將它複製或包裹它......或者可能存在安全問題。
- 同樣可能適用於與安全無關的上下文;例如
ArrayList.toArray(...)
將列表複製到單獨的數組中,而不是返回列表的後備數組。 (類似於getChars()
的String
,StringBuffer
等)這就是保持抽象邊界,以便課堂上不會「破壞」另一個邊界。 - 如果目標對象的吸氣劑返回一個可變對象(或陣列)AND返回的對象是該對象的內部狀態的一部分BUT目標對象的API /抽象邊界設計爲「多孔」(例如出於性能的原因),那麼複製可能會自我失敗。
其中,3是唯一克隆是嚴格強制性的情況。在2,4和5中,你可能會爭辯說,這是你如何爲類,庫,應用程序設計公共(或內部)API的問題。往往有許多可行的選擇。
+0
@StephenC如果你需要在獲取器中克隆對象的時候可以舉一些例子,那將是非常好的可變對象 –
相關問題
- 1. Ruby:對象深度複製
- 2. S4對象深度複製
- 3. 更改要複製的對象時的深度複製行爲
- 4. 以角度深度複製對象?
- 5. 對象的深度複製Ruby
- 6. 是否可以在Flex中進行深度複製?
- 7. 深度複製2維對象陣列
- 8. 如何深度複製DateTime對象?
- 9. 避免在C#中進行深度複製的解決方案
- 10. 如何在java中深度複製對象?
- 11. 在Java中使用構造函數進行深度複製
- 12. 如何在覈心數據中對NSManagedObject進行深層複製
- 13. 深度複製Java中
- 14. 如何在C#.NET中的不同類型的對象之間進行深度複製
- 15. ngModel的深度對象創建機制
- 16. 在python中,我將如何對特定深度的字典進行深層複製?
- 17. 如何深在JavaScript複製對象的對象不是數組
- 18. 深度複製一個簡單的Python對象
- 19. 如何深度複製包含lambda表達式的對象?
- 20. 自定義對象列表的深度複製
- 21. 包含界面的深度複製對象
- 22. 深度複製const的指針const對象
- 23. 未深度複製的簡單Java對象
- 24. AngularJS改變深度範圍對象值
- 25. For循環在python不操縱原始對象,而是執行深度複製
- 26. elisp的深度複製 - consing
- 27. 繪製畫布深度對象
- 28. 在C ... malloc中深度複製數組?
- 29. 如何在Ruby中深度複製Proc?
- 30. 如何執行Objective-C深度複製
對不起,但「它會是開銷」顯然進入「給我你的意見」球場。從這個意義上說,你的問題不適合這裏。我的意見:這真的取決於。如果您的設計在返回副本的情況下效果更好,請執行此操作。如果各方都在處理**相同的**對象很重要,那麼也許您不會創建克隆。 – GhostCat
半相關:http://stackoverflow.com/questions/19192762/inefficiency-of-defensive-copy-in-java – jaco0646