更新時(shí)間:2020-03-12 09:19:07 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2727次
一、類加載
定義
當(dāng)程序要使用某個(gè)類時(shí),如果該類還未被加載到內(nèi)存中,則系統(tǒng)會(huì)通過(guò)加載,連接,初始化三步來(lái)實(shí)現(xiàn)對(duì)這個(gè)類進(jìn)行初始化
加載
就是指將.class文件讀入內(nèi)存,并為之創(chuàng)建一個(gè)Class對(duì)象。任何類被使用時(shí)系統(tǒng)都會(huì)建立一個(gè)Class對(duì)象。
連接
驗(yàn)證是否有正確的內(nèi)部結(jié)構(gòu),并和其他類協(xié)調(diào)一致
準(zhǔn)備負(fù)責(zé)為類的靜態(tài)成員分配內(nèi)存,并設(shè)置默認(rèn)初始化值
解析將類的二進(jìn)制數(shù)據(jù)中的符號(hào)引用替換為直接引用
初始化就是我們以前講過(guò)的初始化步驟
2.加載的時(shí)機(jī)
創(chuàng)建類的實(shí)例
訪問(wèn)類的靜態(tài)變量,或者為靜態(tài)變量賦值
調(diào)用類的靜態(tài)方法
使用反射方式來(lái)強(qiáng)制創(chuàng)建某個(gè)類或接口對(duì)應(yīng)的java.lang.Class對(duì)象
加載某個(gè)類的子類
直接使用java.exe命令來(lái)運(yùn)行某個(gè)主類
真正在使用這個(gè)類型的時(shí)候
二、類加載器的概述和分類
定義
負(fù)責(zé)將.class文件加載到內(nèi)存中,并為之生成對(duì)應(yīng)的Class對(duì)象。雖然我們不需要關(guān)心類加載機(jī)制,但是了解這個(gè)機(jī)制我們就能更好的理解程序的運(yùn)行
2.類加載器的分類
BootstrapClassLoader根類加載器
ExtensionClassLoader擴(kuò)展類加載器
SysetmClassLoader系統(tǒng)類加載器
AppClassLoader應(yīng)用類加載器
3.類加載器的作用
BootstrapClassLoader根類加載器
也被稱為引導(dǎo)類加載器,負(fù)責(zé)Java核心類的加載
比如System,String等。在JDK中JRE的lib目錄下rt.jar文件中
ExtensionClassLoader擴(kuò)展類加載器
負(fù)責(zé)JRE的擴(kuò)展目錄中jar包的加載。
在JDK中JRE的lib目錄下ext目錄
SysetmClassLoader系統(tǒng)類加載器
負(fù)責(zé)在JVM啟動(dòng)時(shí)加載來(lái)自java命令的class文件,以及classpath環(huán)境變量所指定的jar包和類路徑
AppClassLoader加載其他類
負(fù)載一些非核心類和程序猿自己寫的類
4.演示
publicstaticvoidmain(String[]args){
//獲取TestDemo類的類加載器
System.out.println(TestDemo.class.getClassLoader());
}三、自定義類加載器
雙親委派模型
當(dāng)前類加載器從自己已經(jīng)加載的類中查詢是否此類已經(jīng)加載,如果已經(jīng)加載則直接返回原來(lái)已經(jīng)加載的類。
如果沒(méi)有找到,就去委托父類加載器去加載(如代碼c=parent.loadClass(name,false)所示)。父類加載器也會(huì)采用同樣的策略,查看自己已經(jīng)加載過(guò)的類中是否包含這個(gè)類,有就返回,沒(méi)有就委托父類的父類去加載,一直到根類加載器。因?yàn)槿绻讣虞d器為空了,就代表使用根類類加載器作為父加載器去加載
如果根類類加載器加載失?。ɡ缭?JAVA_HOME/jre/lib里未查找到該class),會(huì)使用拓展類加載器來(lái)嘗試加載,繼續(xù)失敗則會(huì)使用AppClassLoader來(lái)加載,繼續(xù)失敗則會(huì)拋出一個(gè)異常ClassNotFoundException,然后再調(diào)用當(dāng)前加載器的findClass()方法進(jìn)行加載
2.好處
主要是為了安全性,避免用戶自己編寫的類動(dòng)態(tài)替換Java的一些核心類,比如String。
同時(shí)也避免了類的重復(fù)加載,因?yàn)镴VM中區(qū)分不同類,不僅僅是根據(jù)類名,相同的class文件被不同的ClassLoader加載就是不同的兩個(gè)類
案例演示
publicclassMyClassLoaderextendsClassLoader{
privateStringpath;
publicMyClassLoader(Stringpath){
super();
this.path=path;
}
@Override
protectedClass<?>findClass(Stringname)throwsClassNotFoundException{
//讀取本地文件
byte[]bs=getBytes(path);
//將字節(jié)數(shù)組裝載成Class對(duì)象
Class<?>clazz=this.defineClass(name,bs,0,bs.length);
returnclazz;
}
privatebyte[]getBytes(Stringpath){
try(
FileInputStreamfis=newFileInputStream(path);
ByteArrayOutputStreambos=newByteArrayOutputStream();
){
byte[]bs=newbyte[1024];
intlen;
while((len=fis.read(bs))!=-1){
bos.write(bs,0,len);
}
returnbos.toByteArray();
}catch(Exceptione){
}
returnnull;
}
}
publicstaticvoidmain(String[]args)throwsException{
MyClassLoaderclassLoader=newMyClassLoader("D:\\Student.class");
Class<?>clazz=classLoader.findClass("com.qianfeng.Student");
//Class<?>class1=Class.forName("com.qianfeng.Student",true,classLoader);
Objectobj=clazz.newInstance();
System.out.println(obj.getClass().getClassLoader());
}四、反射
定義
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法
對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性
這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語(yǔ)言的反射機(jī)制
要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對(duì)象
而解剖使用的就是Class類中的方法,所以先要獲取到每一個(gè)字節(jié)碼文件對(duì)應(yīng)的Class類型的對(duì)象
說(shuō)白了就是獲取一個(gè)類的骨架
2.獲取字節(jié)碼的三種方式
對(duì)象.getClass()
類名.class
Class類中靜態(tài)方法forName("類名")
3.演示
publicstaticvoidmain(String[]args)throwsException{
Studentstudent=newStudent();
Class<?>clazz1=student.getClass();
Class<?>clazz2=Student.class;
Class<?>clazz3=Class.forName("com.qianfeng.Student");
}五、反射獲取構(gòu)造函數(shù)
定義
Class類的newInstance()方法是使用該類無(wú)參的構(gòu)造函數(shù)創(chuàng)建對(duì)象
如果一個(gè)類沒(méi)有無(wú)參的構(gòu)造函數(shù),就不能這樣創(chuàng)建了,可以調(diào)用Class類的getConstructor(String.class,int.class)方法獲取一個(gè)指定的構(gòu)造函數(shù)然后再調(diào)用Constructor類的newInstance("張三",20)方法創(chuàng)建對(duì)象
2.演示
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("com.qianfeng.Student");
Studentobject=(Student)clazz.newInstance();
object.method();
}
以上就是動(dòng)力節(jié)點(diǎn)Java培訓(xùn)機(jī)構(gòu)小編介紹的“Javaweb學(xué)習(xí)視頻:反射動(dòng)態(tài)代理”的內(nèi)容,希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)