Java 反射機(jī)制的實(shí)例詳解
Java 反射機(jī)制的實(shí)例詳解
前言
今天介紹下Java的反射機(jī)制,以前我們獲取一個(gè)類的實(shí)例都是使用new一個(gè)實(shí)例出來。那樣太low了,今天跟我一起來學(xué)習(xí)學(xué)習(xí)一種更加高大上的方式來實(shí)現(xiàn)。
正文
Java反射機(jī)制定義
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語言的反射機(jī)制。 用一句話總結(jié)就是反射可以實(shí)現(xiàn)在運(yùn)行時(shí)可以知道任意一個(gè)類的屬性和方法。
反射機(jī)制的優(yōu)點(diǎn)與缺點(diǎn)
為什么要用反射機(jī)制?直接創(chuàng)建對(duì)象不就可以了嗎,這就涉及到了動(dòng)態(tài)與靜態(tài)的概念
靜態(tài)編譯:在編譯時(shí)確定類型,綁定對(duì)象,即通過。
動(dòng)態(tài)編譯:運(yùn)行時(shí)確定類型,綁定對(duì)象。動(dòng)態(tài)編譯最大限度發(fā)揮了java的靈活性,體現(xiàn)了多態(tài)的應(yīng)用,有以降低類之間的藕合性。
優(yōu)點(diǎn)
可以實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建對(duì)象和編譯,體現(xiàn)出很大的靈活性,特別是在J2EE的開發(fā)中它的靈活性就表現(xiàn)的十分明顯。比如,一個(gè)大型的軟件,不可能一次就把把它設(shè)計(jì)的很完美,當(dāng)這個(gè)程序編譯后,發(fā)布了,當(dāng)發(fā)現(xiàn)需要更新某些功能時(shí),我們不可能要用戶把以前的卸載,再重新安裝新的版本,假如這樣的話,這個(gè)軟件肯定是沒有多少人用的。采用靜態(tài)的話,需要把整個(gè)程序重新編譯一次才可以實(shí)現(xiàn)功能的更新,而采用反射機(jī)制的話,它就可以不用卸載,只需要在運(yùn)行時(shí)才動(dòng)態(tài)的創(chuàng)建和編譯,就可以實(shí)現(xiàn)該功能。
缺點(diǎn)
對(duì)性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿足我們的要求。這類操作總是慢于只直接執(zhí)行相同的操作。
理解Class類和類類型
想要了解反射首先理解一下Class類,它是反射實(shí)現(xiàn)的基礎(chǔ)。
類是java.lang.Class類的實(shí)例對(duì)象,而Class是所有類的類(There is a class named Class) 對(duì)于普通的對(duì)象,我們一般都會(huì)這樣創(chuàng)建和表示:
Code code1 = new Code();
上面說了,所有的類都是Class的對(duì)象,那么如何表示呢,可不可以通過如下方式呢:
Class c = new Class();
但是我們查看Class的源碼時(shí),是這樣寫的:
private Class(ClassLoader loader) {
classLoader = loader;
}
可以看到構(gòu)造器是私有的,只有JVM可以創(chuàng)建Class的對(duì)象,因此不可以像普通類一樣new一個(gè)Class對(duì)象,雖然我們不能new一個(gè)Class對(duì)象,但是卻可以通過已有的類得到一個(gè)Class對(duì)象,共有三種方式,如下:
Class c1 = Code.class;
這說明任何一個(gè)類都有一個(gè)隱含的靜態(tài)成員變量class,這種方式是通過獲取類的靜態(tài)成員變量class得到的
Class c2 = code1.getClass();
code1是Code的一個(gè)對(duì)象,這種方式是通過一個(gè)類的對(duì)象的getClass()方法獲得的
Class c3 = Class.forName(“com.trigl.reflect.Code”);
這種方法是Class類調(diào)用forName方法,通過一個(gè)類的全量限定名獲得 ,這里,c1、c2、c3都是Class的對(duì)象,他們是完全一樣的,而且有個(gè)學(xué)名,叫做Code的類類型(class type)。 這里就讓人奇怪了,前面不是說Code是Class的對(duì)象嗎,而c1、c2、c3也是Class的對(duì)象,那么Code和c1、c2、c3不就一樣了嗎?為什么還叫Code什么類類型?這里不要糾結(jié)于它們是否相同,只要理解類類型是干什么的就好了,顧名思義,類類型就是類的類型,也就是描述一個(gè)類是什么,都有哪些東西,所以我們可以通過類類型知道一個(gè)類的屬性和方法,并且可以調(diào)用一個(gè)類的屬性和方法,這就是反射的基礎(chǔ)。
舉個(gè)簡(jiǎn)單例子代碼:
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
//第一種:Class c1 = Code.class;
Class class1=ReflectDemo.class;
System.out.println(class1.getName());
//第二種:Class c2 = code1.getClass();
ReflectDemo demo2= new ReflectDemo();
Class c2 = demo2.getClass();
System.out.println(c2.getName());
//第三種:Class c3 = Class.forName("com.trigl.reflect.Code");
Class class3 = Class.forName("com.tengj.reflect.ReflectDemo");
System.out.println(class3.getName());
}
}
執(zhí)行結(jié)果:
com.tengj.reflect.ReflectDemo com.tengj.reflect.ReflectDemo com.tengj.reflect.ReflectDemo
Java反射相關(guān)操作
前面我們知道了怎么獲取Class,那么我們可以通過這個(gè)Class干什么呢?
總結(jié)如下:
獲取成員方法Method
獲取成員變量Field
獲取構(gòu)造函數(shù)Constructor
下面來具體介紹
獲取成員方法信息
單獨(dú)獲取某一個(gè)方法是通過Class類的以下方法獲得的:
public Method getDeclaredMethod(String name, Class c){
}
如有疑問請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
SpringBoot 策略模式實(shí)現(xiàn)切換上傳文件模式
策略模式是指有一定行動(dòng)內(nèi)容的相對(duì)穩(wěn)定的策略名稱,這篇文章主要介紹了SpringBoot 策略模式 切換上傳文件模式,需要的朋友可以參考下2023-11-11
Java?MethodHandles介紹與反射對(duì)比區(qū)別詳解
這篇文章主要為大家介紹了Java?MethodHandles介紹與反射對(duì)比區(qū)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Java方法遞歸的形式和常見遞歸算法(方法遞歸結(jié)合File類查找文件)
方法遞歸方法直接調(diào)用自己或者間接調(diào)用自己的形式稱為方法遞歸( recursion),遞歸做為一種算法在程序設(shè)計(jì)語言中廣泛應(yīng)用,這篇文章主要介紹了Java方法遞歸的形式和常見遞歸算法-方法遞歸結(jié)合File類查找文件,需要的朋友可以參考下2023-02-02
Spring Boot 集成 Quartz 使用Cron 表達(dá)式實(shí)現(xiàn)定
本文介紹了如何在SpringBoot項(xiàng)目中集成Quartz并使用Cron表達(dá)式進(jìn)行任務(wù)調(diào)度,通過添加Quartz依賴、創(chuàng)建Quartz任務(wù)、配置任務(wù)調(diào)度以及啟動(dòng)項(xiàng)目,可以實(shí)現(xiàn)定時(shí)任務(wù)的執(zhí)行,Cron表達(dá)式提供了靈活的任務(wù)調(diào)度方式,適用于各種復(fù)雜的定時(shí)任務(wù)需求,感興趣的朋友一起看看吧2025-03-03

