更新時(shí)間:2022-10-20 10:20:51 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1642次
java反射機(jī)制可以動(dòng)態(tài)獲取類的各種信息,如方法、屬性等。并且可以生成該類的對(duì)應(yīng)實(shí)例;可以調(diào)用任何對(duì)象的任何方法,即jvm(虛擬機(jī))允許代碼在運(yùn)行過程中獲取類的內(nèi)部信息
在使用反射機(jī)制時(shí),一個(gè)非常重要的Class就是Class,它是由類加載后的 JVM(虛擬機(jī))
在運(yùn)行時(shí)確定任何對(duì)象的類
在運(yùn)行時(shí)構(gòu)造任何類的對(duì)象;
在運(yùn)行時(shí)確定任何類的成員變量和方法;
在運(yùn)行時(shí)調(diào)用任意對(duì)象的方法;
生成動(dòng)態(tài)代理;
優(yōu)勢(shì):
運(yùn)行時(shí)可以判斷類型并動(dòng)態(tài)加載類,提高了代碼的靈活性。訪問不可訪問的成員變量等;獲取類的方法和成員變量;
缺點(diǎn):
Java反射相當(dāng)于一系列解釋操作。這個(gè)過程需要通知jvm(虛擬機(jī)),所以性能比直接源碼慢很多。它無(wú)法識(shí)別編譯器中的錯(cuò)誤。錯(cuò)誤只能在運(yùn)行時(shí)發(fā)現(xiàn),增加了難度
java.lang.Class //類
java.lang.reflect.Constructor //構(gòu)造方法
java.lang.reflect.Field //類的成員變量
java.lang.reflect.Method //類方法
java.lang.reflect.Modifier //訪問權(quán)限
模塊化開發(fā),通過反射調(diào)用對(duì)應(yīng)的字節(jié)碼;
動(dòng)態(tài)代理設(shè)計(jì)模式
Spring和hibernate框架等
一個(gè)結(jié)合注解的框架,如Retrofit
例子:
JDBC編程中,加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)時(shí)應(yīng)用反射機(jī)制;
Class.forName("com.mysql.jdbc.Driver") 加載驅(qū)動(dòng)類并在DriverManager類中注冊(cè)驅(qū)動(dòng)類實(shí)例。
獲取類對(duì)象的三種方法
1.使用已知對(duì)象的“getClass()”方法,例如:
/*
* 如何獲取字節(jié)碼對(duì)象:
* 要使用此方法,您必須指定特定的類并創(chuàng)建對(duì)象。
*/
公共類 GetClassTest {
/*類的方法和屬性*/
公共靜態(tài)無(wú)效get(){
GetClassTest 測(cè)試 = 新的 GetClassTest();
Class class = test.getClass();//可以返回<span style = "font family: Arial, Helvetica, sans serif;" > getclasstest 類的類對(duì)象</ span>
}
}
2.Class.forName("類名"),例如
/*
* 只要傳遞給定類的字符串名稱,就可以獲得該類,擴(kuò)展性更強(qiáng)。
* 但是可以通過使用Class中的方法來完成。
* 這個(gè)方法是forName
* 這種方法只要有名字就更方便,擴(kuò)展性更好。
*/
公共類 ForNameTest {
/*類的方法和屬性*/
公共靜態(tài)無(wú)效get(){
Class class = Class.forName("Package name.RefClass");//加載RefClass Class,生成對(duì)應(yīng)Class對(duì)象,初始化RefClass Class;
}
}
3.類名class,例如:
/*
* 任何數(shù)據(jù)類型都有一個(gè)靜態(tài)屬性Class來獲取其對(duì)應(yīng)的類圖像。
* 比較簡(jiǎn)單,但是我們還是需要在類中顯式使用靜態(tài)成員。
* 擴(kuò)展不夠。
*/
公共類 ClassTest {
/*類的方法和屬性*/
公共靜態(tài)無(wú)效get(){
Class class = RefClass.class;//加載RefClass Class并生成對(duì)應(yīng)的Class對(duì)象,但RefClass Class沒有初始化;
}
}
可通過類對(duì)象獲取的信息
class.getName();//獲取類名包含包名的路徑
class.getPackage();//獲取類的包信息
class.getSimpleName();//獲取類名
class.getModifiers();//獲取類訪問權(quán)限
class.getDeclaredClasses();//內(nèi)部類
class.getDeclaringClass();//外部類
class.getType();//字段類型
班級(jí)。getModifiers();//字段訪問修飾符
class.getMethods();// 獲取類中的所有公共方法,包括父類中的方法
class.getDeclaredMethods();// 獲取類中的所有方法,包括公共和私有方法,但不包括父類中的方法
class.isPrimitive();//判斷是否為基本類型
class.isArray();//判斷是否為集合類
class.isAnnotation();//判斷是否為注解類
class.isInterface();//判斷是否為接口類
class.isEnum();//判斷是否為枚舉類
class.isAnonymousClass();//判斷是否為匿名內(nèi)部類
class.isAnnotationPresent(Deprecated.class);//判斷是否被注解類修改
獲取方法的方法名和參數(shù)
//遍歷所有方法
for (方法 m : 聲明方法){
// 獲取方法名
System.out.print(m.getName()+"(");
// 用于判斷是否為第一個(gè)參數(shù)
布爾 isFrist = true;
// 獲取方法的所有參數(shù)類
類<?>[] parameterTypes = m.getParameterTypes();
//遍歷所有參數(shù)
for (Class<?> clazz : parameterTypes){
如果(isFrist){
System.out.print(clazz.getName());
isFrist = 假;
} 別的 {
System.out.print("," + clazz.getName());
}
}
System.out.println(");");
}
以上就是關(guān)于“Java反射機(jī)制的應(yīng)用”介紹,大家如果想了解更多相關(guān)知識(shí),不妨來關(guān)注一下動(dòng)力節(jié)點(diǎn)的Java在線學(xué)習(xí),里面的課程內(nèi)容細(xì)致全面,很適合沒有基礎(chǔ)的小伙伴學(xué)習(xí),希望對(duì)大家能夠有所幫助哦。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)