五:java類加載

Java 類型的加載和鏈接都是在運行期間,這樣可能會有性能開銷,可是卻能提供動態擴展的語言特性。
git

解析可能在初始化以後進行數組

vm規範規定了四個點必須對類進行初始化:網絡

  1. 遇到new ,getstatic,putstatic, invokestatic幾個指令的時候。也就是new, 使用設置靜態變量,引用靜態方法的時候 訪問靜態變量只會形成當前類的初始化,不會初始化子類,這裏還要注意,對於被final修飾、在編譯器已經放入常量池的靜態屬性不會觸發初始化。 new 數組是不會初始化類的
  2. reflect包的方法對類進行反射調用的時候
  3. 初始化時要先初始化父類
  4. 虛擬機啓動時要指定主類,主類會先初始化

過程

加載

1. 根據全名獲取二進制字節流                沒有指明流的來與,因而能夠是jar包,網絡,動態代理在運行時生成
2. 在方法區生成該類的運行時數據結構
3. 在堆上建立Class對象,做爲對方法區數據訪問入口

驗證

要求知足字節碼格式規範等

準備

爲類變量分配內存並設定初始值的階段,  不涉及實例變量,都在方法區進行。

解析

將常量池內的符號引用替換爲直接引用的過程。
符號引用就是字面量, 沒有指向實際的內存,只是表示知道這個類有這個引用,但具體引用到哪裏還不知道
直接引用,  是鏈接了實際目標的符號引用

初始化

執行類client()方法的過程, 由編譯器收集的類變量賦值動做和static方法塊合併成的。
虛擬保證client是順序執行的,所以要注意若是static預發快中有死循環會形成阻塞

類加載器

 

  1. 工做流程: 收到加載請求後,交給父加載器去完成, 父完不成才會嘗試本身完成。 以下是個過程 Class c = findClass(name); if(c == null){ c = parent.loadClass(name); } if(c == null){ // 父不行了,本身來 c = findClass(name) } return c;
  2. 破壞雙親委派
    1. JNDI 雙親委派解決不了基礎類須要調用用戶代碼的狀況 JNDI服務由啓動加載器加載,可是其用到的接口類卻由各個廠商提供,啓動加載器就會找不到,引入了線程上下文加載器,須要使用Thread.setContextClassLoader()進行設置。JNDI就是用了這個加載器
    2. OSGI, 每一個boundler一個類加載器,import的類委託給export的類加載器去加載。
相關文章
相關標籤/搜索