成員變數什麼時候載入
private是用來在編譯期檢測錯誤的,不是用來在執行期保證hard private的。手動@JavaScript。如果你認為在物件外部訪問某個成員很可能導致物件的行為出現問題,那麼你把它設定為private,從而編譯器可以替你發現那些錯誤用法,這也就夠了。
而封裝的意義在於概念和實現不一致。比如我實現一個線性表,但是其實我用了一個數組,它明明可以隨機訪問嘛。但是具體到這個線性表,它在概念上不能隨機訪問,所以我把加上private。
private並不是解決“安全”問題的。安全是指不讓程式碼被非法看到/訪問。但是隻要人能拿到程式碼,總會有辦法去檢視和改變程式碼。
反射跟這個情況差不多。個人理解反射是為了給需要極高靈活性、可擴充套件性的機制或框架提供的,比如jdbc,比如spring。因為有了反射。
當
你在用spring
得
IoC的時候,你知道你要“注入”,不管它是不是private,你知道“注入”是你自己控制的,是你設計好的效果。那麼透過springIoC利用反射幫你注入一些private property是再正常不過的用法。
用public,表示這個是安全介面,如果程式碼升級了,沒有特殊宣告的情況下,這些public的介面用法應該不變。(程式碼維護者應該保證public的安全性)
說到底,執行時就“不可能有”hard private,不然CPU為什麼要提供保護模式,intel的那幾個漏洞為什麼那麼重要,為什麼要搞SGX。如果執行時可以存在hard private,那麼語言把敏感資料作為hard private保護就完了,還省了segfault。
相反的,寫成private,就是不希望你直接使用它,在新的程式碼版本中,這些private的變數和方法有可能去掉或者改變用途。(程式碼維護者不保證private的安全性)
在這個語境裡,反射作為一個有益的補充功能,關鍵時刻可以救命。但它的設計沒有完整到可以取代 private 的程度。或者打個不恰當的比方,它是剁骨刀,你要用來切菜也行,但菜刀仍然有自己的價值。
正因為有反射,private 才能真正發揮價值。private 這種機制是為了防止用這個類的人腦殘搞出些天坑,然而萬一寫這個類的作者自己腦殘,你怎麼破?
很簡單,語言上的這些修飾符號,面向的是設計,
並不是為了解決安全性問題,僅僅是類
設計者,告訴呼叫者,哪些方法/欄位可以使用,哪些是不可以使用。
如果呼叫者強行使用私有成員,設計者並不保證功能的正確性。