jave是安全的,這展現在多個方面,其中之一就是java類的加載,而且java類的加載安全機制展現出來的是一種原則,就是保持資訊的單向流動而不是 雜糅的雙向依賴總是一件好事,因為首先這樣做會更加安全,其次這樣做會降低耦合,更高層的意義上,這樣做可以使得事情變得清晰明了,最後一點具有普遍性,我們的社會中的很多機構就是這麼設計的。
關于java的類加載機制原理請看jvm規範,這裡不再贅述。我想java類加載器中最安全的展現就在于類加載請求的逐級單向向上傳遞,這裡的加載請求正是資訊的單向流動。java之是以這麼做是因為它的執行環境的複雜性,衆所周知,java來自任何地方,可以到任何地方執行,這種任意的不确定性使得 java類比c++類更能展現出其整體性,c++類特性也許僅僅在開發階段有意義,但是java類的意義卻不但在開發而且在執行階段,java虛拟機執行 的就是類,是以類必須作為一個整體傳輸了需要它的任何地方,既然有地方需要它,那麼必然要加載它到記憶體,java類就好像一個貨物一樣,那麼加載方式是任 意的嗎?就好像c和c++那樣載入記憶體就拉倒了嗎?
我們想象一下卡車貨運就明白了,如果任何人都可以往卡車裡面裝貨并且在任何地方卸貨,那是危險的,但是那是最危險的嗎?不。因為誰有權裝貨誰有權卸貨是另一個部門的事情,對于貨物本身來說,最重要的莫過于貨的内容,我們都知道上車前無論是人還是物,都要進行安檢,就是這樣道理,如果本來人家要的是雞蛋,你給人家 送個炸彈,那收貨的人就笑了,于是安檢是很重要的一個環節,不但裝貨的時候要安檢,卸貨的時候還要安檢,以确認就是收貨人要的貨。對于java類這種在互 聯網上運輸的二進制的數字貨物而言,安檢也是必須的,jvm實作了一套基于“委托”的類載入機制。大緻意思就是一個類裝載器載入的類隻能主動通路相同類裝載器載入的類以及該類裝載器的父裝載器載入的類,也就是裝載一個類的時候,類裝載請求逐級單向向上送出,最終第一個收到請求的是根裝載器,如果根裝載器不 能裝載才向下沿着上來的方向回溯繼續傳遞類裝載請求,越往上類裝載器的可信任級别越高,實際上,根裝載器就是你的java運作環境的一部分,這種方式不能 保證事情是絕對安全的,但是最起碼可以将不安全因素的比例降至最低。
我們來看一下為什麼這種方式可以實作。我們想想便知,真正要執行的java類都是程式員自己寫的java類,不是java環境的核心類,但是雖然是自己寫 的類,它還是繼承了核心類(考慮Object類),而且所有的内部邏輯不是直接繼承或間接繼承了核心類就是直接包含或間接包含了核心類,OO的思想無外乎 就這兩種,包含和繼承。核心類是最終幹活的類,而我們自己寫的類僅僅是一些業務邏輯的封裝,最終幹活的類就是一系列的工具類,我們必須確定這些核心類不被替換,確定它們的安全(想想看,它們一旦被替換,所有用到它們的都将遭殃,核心類的重用度是最高的),java規範又規定,一個類必須在它的父類初始化後才能被初始化,這樣的話,核心類總是先被根裝載器載入記憶體,java類裝載器在載入一個類時,如果它已經被載入了,那麼将放棄這次載入行為,這樣的話,很少有機會可以替換核心類,于是實作了安全。
本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1274002