java初始化加载类_Java 类的加载和初始化
直接從書上抄來的,自己寫一遍加深印象
類的加載
加載就是通過指定的類全限定名,獲取此類的二進(jìn)制字節(jié)流(可以是clazz文件或者直接內(nèi)存讀取或者遠(yuǎn)程網(wǎng)絡(luò),jar包等),然后將此二進(jìn)制字節(jié)流轉(zhuǎn)化為方法區(qū)的數(shù)據(jù)結(jié)構(gòu),在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象。
java.lang.Class這個(gè)類用于維護(hù)目標(biāo)類,包括讀取字段 讀取構(gòu)造函數(shù),讀取方法,創(chuàng)建實(shí)例(newInstance)等等。
class對(duì)象可以通過Class.forName("java.lang.String")獲取,或者直接String.class獲取,
或者"java.lang.String".getClass(),注意getClass方法是java.lang.Object中定義的,屬于native方法
定義的類不一定是第一次使用的時(shí)候的才加載也可以預(yù)先加載,java虛擬機(jī)桓范允許系統(tǒng)預(yù)先加載某些類。
當(dāng)類被加載后,系統(tǒng)會(huì)生成對(duì)應(yīng)的class對(duì)象,接著進(jìn)入連接階段。連接階段負(fù)責(zé)把類的二進(jìn)制數(shù)據(jù)合并到j(luò)re中,具體分三階段
1.驗(yàn)證文件是否合法,不會(huì)危害虛擬機(jī)的安全
2.為類的變量分配內(nèi)存 設(shè)置默認(rèn)值
3.將類的二進(jìn)制數(shù)據(jù)中的符號(hào)引用替換成直接引用
類的初始化
在初始化階段,主要對(duì)類變量執(zhí)行初始化。將常量池(里面存儲(chǔ)了我們編寫的java類的類和接口的全限定名,字段的名稱和描述符)中的符號(hào)引用轉(zhuǎn)換為直接引用的過程。設(shè)置初始化一般有2種方法,1是聲明的時(shí)候直接賦值,2是使用靜態(tài)代碼塊
如果這個(gè)類還存在父類,那么先需要初始化直接父類,所以jvm最先初始化Object
如果類包含初始化語句則執(zhí)行
什么時(shí)候會(huì)初始化?
1.創(chuàng)建實(shí)例 比如new 反射創(chuàng)建實(shí)例 反序列化等
2.調(diào)用某個(gè)類的方法(靜態(tài)的)
3.訪問某個(gè)類或接口的類變量
4.使用反射創(chuàng)建某個(gè)類或接口的class對(duì)象,例如class.forName("xx")
5.初始化某個(gè)類的子類 子類的所有父類都會(huì)初始化
注意一個(gè)final類型的類變量,如果編譯時(shí)就確定了具體的指,那么這個(gè)類變量相當(dāng)于宏變量,編譯器會(huì)執(zhí)行優(yōu)化,調(diào)用這個(gè)變量的地方直接替換成該值,這個(gè)變量相當(dāng)于不存在了。變量調(diào)用自然不會(huì)導(dǎo)致該類的初始化。
ClassLoader.loadClass()只會(huì)導(dǎo)致類被加載,Class.forName()才會(huì)執(zhí)行類的初始化
類加載器
類加載器負(fù)責(zé)加載所有的類,系統(tǒng)為所有被載入內(nèi)存的類生成對(duì)應(yīng)的java.lang.Class實(shí)例。一個(gè)一旦被加載,則不會(huì)被再次載入了。每個(gè)被載入內(nèi)存的類,都有一個(gè)唯一標(biāo)識(shí)(類的全限定類名和其類加載器)
加載器規(guī)則
1.加載一個(gè)類時(shí),該類所依賴和引用的其他類都由改類的加載器負(fù)責(zé)載入
2.如果一個(gè)類存在父類,則優(yōu)先嘗試使用父類的加載器加載該類
3.所有被載入的類都會(huì)被緩存,讀取類的時(shí)候,會(huì)優(yōu)先使用緩存
總結(jié)
以上是生活随笔為你收集整理的java初始化加载类_Java 类的加载和初始化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速去除PDF的打开密码和限制(四种方法
- 下一篇: java高级类_Java高级类特性(一)