Class進(jìn)入到內(nèi)存有三大步,分別是loading,linking,initlalizing.
?? ????上一次說到為什么要搞雙親委派模式,主要是為了安全凉逛,如果任何一個(gè)class都可以把它load到內(nèi)存中踊跟,打包給客戶,然后把密碼存儲(chǔ)成String對(duì)象涉茧,我可以把密碼發(fā)給自己赴恨,那就不安全了,雙親委派就不會(huì)出現(xiàn)這樣伴栓,自定義ClassLoader加載一個(gè)java.lang.String他就產(chǎn)生了警惕伦连,他先去上面查有沒有加載過雨饺,上面有加載過直接返回給你,不給你重新加載惑淳。
?? ????接下來繼續(xù)講加載器
?? ????加載器父加載器不是“類加載器的加載器”额港,也不是“類加載器的父類加載器”。
可以看看累加載器的范圍歧焦,它是來自于Launcher的源碼移斩。打印一個(gè)Class文件的toString的方法他默認(rèn)顯示是類的名字加上后面一個(gè)哈希code碼。這個(gè)類的名字是什么意思呢绢馍?是sun->misc包下面的Launcher類向瓷,這個(gè)類下面有一個(gè)內(nèi)部類叫ExeClassLoader,Launcher就是ClassLoader一個(gè)包裝類啟動(dòng)類舰涌,在這個(gè)類里面可以看出猖任,Bootstrap它加載的路徑是我們核心路徑而ext.dirs這個(gè)屬性指定的哪些路徑呢,為什么我們的AppClassCloader指定的是java.class.path這個(gè)路徑呢舵稠?其實(shí)所有的代碼都來自與Launcher的源碼超升。
自定義類加載器
自定義類加載器有幾個(gè)步驟:
1.繼承Classloader
2.重寫模板方法findClass
??-調(diào)用defineClass
3.自定義類加載器加載自加密的class
??-防止反編譯
??-防止篡改
簡(jiǎn)單的說就是從classloader繼承,繼承完了之后重寫它的findClass方法哺徊,在finanClass方法中室琢,找到load進(jìn)來的那個(gè)二進(jìn)制的內(nèi)容,load完了之后再把這部分的內(nèi)容轉(zhuǎn)換成class類對(duì)象落追,用defindclass盈滴。自己編譯好了,手動(dòng)加密轿钠。
lazylaoding
jvm虛擬機(jī)的實(shí)現(xiàn)都是用的懶加載就是什么時(shí)候需要這個(gè)類的時(shí)候我才去加載
嚴(yán)格的講應(yīng)該叫l(wèi)azyInitializing巢钓,jvm規(guī)范并沒有規(guī)定何時(shí)加載,但是嚴(yán)格規(guī)定了什么時(shí)候必須初始化
??-new getstatic putstatic invokestatic指令疗垛,訪問final變量除外
??-java.lang.reflect對(duì)類進(jìn)行反射調(diào)用時(shí)
??-初始化子類的時(shí)候症汹,父類首先初始化
??-虛擬機(jī)啟動(dòng)時(shí),被執(zhí)行的主類必須初始化
??-動(dòng)態(tài)語言支持java.lang.invoke.MethodHandle解析的結(jié)果為REF_getstatic REF_getstatic REF_invokestatic的方法句柄時(shí)贷腕,該類必須初始化背镇。