JAVA 不同類載入器命名空間的理解,java命名空間
以前一直有這樣一個疑惑:
都說在JAVA中,由不同類載入器載入的類在虛擬機器中位於不同的命名空間下,不同命名空間下的類相互不可見。
這讓我產生了一個迷惑:如果有一個類A使用了java.util.List類,為什麼在運行時會沒有錯誤。因為按照類載入的雙親委派機制,自己寫的類A一般由系統類別載入器載入,而java.util.List肯定是由啟動類載入器(也叫Root類載入器)載入的,所以這兩個類應該不在一個命名空間下。那在運行時為什麼類A還 是能訪問到java.util.List?
現在搞明白了,原因如下:
首先我們明白,每一個JAVA類經過載入後,在虛擬機器中都有一個對應的類型。
再有以下概念:如果類A被系統類別載入器載入,那麼該系統類別載入器就是此A在虛擬機器中對應類型的初始類載入器
Java虛擬機器為每個類載入器維護了一個表,其中記錄了將該類載入器作為初始類載入器的所有類型。在載入一個類時,虛擬機器使用這些列表來決定是否一個類已經被特定的類載入器載入過了(如果該類型在當前類載入器的列表中,就說明已經載入過了,就不再載入)。
再回到剛到A使用java.util.List的例子,當A被載入後,解析到A使用了List,就會請求載入java.util.List。根據類的載入原理及雙親委派機制。會先請類A的類載入器,即系統類別載入器載入java.util.List,系統類別當然載入不了這個List,所以它會委派給自己的父載入器,即擴充類載入器;同理,最終會由根據類載入器載入這個java.util.List,並成功返回。
根據Java虛擬機器規範規定,在這個過程中涉及的所有類載入器--即從系統類別載入器到根類載入器間,參與過載入的,都被標記為該類型的初始類載入器。換句話說,java虛擬機器為在第一個類載入器維護的表中添加一個類型,用來標明此載入器是該類型的初始類載入器。
這樣就不難理解類A為何可以使用java.util.List。儘管它們不是由一個載入器載入的,因為在系統類別載入器的表中,即維護了類型A,也維護了類型List。
深入java虛擬機器中類裝載器解釋中 為何是雙親委派模式 而不叫單親委派模式?類裝載器中提到
深入java虛擬機器中類裝載器解釋中 為什麼是雙親委派模式 而不叫單親委派模式呢?
這就是名稱問題而已,不管是繼承自一個類還是實現多個介面,本質都要用到invoke指令,
雙親單親僅僅是個名稱而已。
方法區中儲存著的 類 型資訊。命名空間 這命名空間在這裡指的是所有 類 的命名空間,不同於類執行個體的命名空間,開發人員也沒有辦法去強行指定類執行個體放在哪個命名空間中。不需要關心,因為不需要關心具體的記憶體資源釋放,透明的。只所以叫方法區我想不僅僅是因為儲存了類型資訊,而是為索引或者其它必要的操作提供了很多方法,而這些方法對開發人員來說幾乎接觸不到罷了。方法區更像是一個提供了管理類等操作的容器。
java的包與命名空間有什不同?
1.java裡只有類,所以只需要把類定義在各自的包裡就可以避免重複了.c++的命名空間裡,不但可以包括類,還可以包括函數,變數,模板等.
2.java裡在類的第一行用packge 包名 就可以把類放到包裡了
c++裡用namespace 命名空間名{類,函數,變數,模板等};
一般意義上,C++中多了標頭檔,裡面可以進行函數定義,變數聲明。。
這個問題關鍵應該在於對於兩種語言的特點的瞭解。
Java裡面都是CLASS,放包裡,而且名字不能重複。
C++可以同名,但是尾碼不能一樣。。
都是一種對來源程式進行分類打包,便於調用
參考資料:zhidao.baidu.com/question/40551357.html