簡體   English   中英

葉節點類中的Sealed關鍵字

[英]Sealed keyword in leaf node classes

雖然我知道出於安全原因可以使用密封的,但仍有少數人在葉節點上使用密封的關鍵字作為優化技術。

這如何幫助優化? 為什么編譯器不夠聰明,無法自行解決?

假設您有一個在葉子類中覆蓋的虛擬方法。 當然,這不會被進一步覆蓋,因此JIT編譯器可以潛在地內聯調用該方法,以用於已知屬於該葉類的目標。 請注意,我不知道JIT是否實際上執行了此優化。

請注意,在Java中,HotSpot JVM甚至可以對非最終類執行此優化,因為它是一次多次傳遞的JIT:它可以樂觀地假設沒有任何東西可以覆蓋虛擬方法,如果某個類曾經存在過,則可以撤消其優化。加載, 會覆蓋它。 當然,在Java中默認使用虛擬方法的情況下,這比在C#中要大得多。 (即使違約不應該的問題,他們顯然做的。)

就個人而言,我並不是特別出於優化或安全原因而使用sealed :之所以使用它,是因為(適當地)設計繼承非常困難 我同意“為繼承而設計或禁止繼承”的概念,並且通常發現,無法從一個類派生出來的偶然痛苦,可以通過擔心繼承的自由得到補償。 YMMV。

不,在優化方面並沒有真正的幫助。 反正我從剖析中看不到什么。

在密封的類中,對虛擬方法的調用可以繞過常規的虛擬方法查找,而直接轉到最派生的虛擬方法實現。 原則上,編譯器/ JIT也可以內聯這些調用。

對於非密封類,編譯器無法解決,因為任何代碼都可以在編譯后出現並從您的類繼承:編譯器必須假定最壞的情況。

這有點不正確。 我寧願用它來確保,如果我不期待繼承我沒有得到繼承。 編譯器仍將所有實例調用(對類)作為虛擬調用發出,但是潛在的JIT可以對其進行不同的優化,並且如果不進行覆蓋,則只需執行null檢查和靜態調用即可。 可能吧。

還有一些更深奧的情況,例如,當特定接口的存在會導致在運行時對它進行不同的處理時-但是要利用這些情況(取決於sealed ),需要通過ILGenerator等生成運行時代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM