Java 反射機制的實例詳解
Java 反射機制的實例詳解
前言
今天介紹下Java的反射機制,以前我們獲取一個類的實例都是使用new一個實例出來。那樣太low了,今天跟我一起來學習學習一種更加高大上的方式來實現(xiàn)。
正文
Java反射機制定義
Java反射機制是指在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。 用一句話總結(jié)就是反射可以實現(xiàn)在運行時可以知道任意一個類的屬性和方法。
反射機制的優(yōu)點與缺點
為什么要用反射機制?直接創(chuàng)建對象不就可以了嗎,這就涉及到了動態(tài)與靜態(tài)的概念
靜態(tài)編譯:在編譯時確定類型,綁定對象,即通過。
動態(tài)編譯:運行時確定類型,綁定對象。動態(tài)編譯最大限度發(fā)揮了java的靈活性,體現(xiàn)了多態(tài)的應用,有以降低類之間的藕合性。
優(yōu)點
可以實現(xiàn)動態(tài)創(chuàng)建對象和編譯,體現(xiàn)出很大的靈活性,特別是在J2EE的開發(fā)中它的靈活性就表現(xiàn)的十分明顯。比如,一個大型的軟件,不可能一次就把把它設計的很完美,當這個程序編譯后,發(fā)布了,當發(fā)現(xiàn)需要更新某些功能時,我們不可能要用戶把以前的卸載,再重新安裝新的版本,假如這樣的話,這個軟件肯定是沒有多少人用的。采用靜態(tài)的話,需要把整個程序重新編譯一次才可以實現(xiàn)功能的更新,而采用反射機制的話,它就可以不用卸載,只需要在運行時才動態(tài)的創(chuàng)建和編譯,就可以實現(xiàn)該功能。
缺點
對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿足我們的要求。這類操作總是慢于只直接執(zhí)行相同的操作。
理解Class類和類類型
想要了解反射首先理解一下Class類,它是反射實現(xiàn)的基礎。
類是java.lang.Class類的實例對象,而Class是所有類的類(There is a class named Class) 對于普通的對象,我們一般都會這樣創(chuàng)建和表示:
Code code1 = new Code();
上面說了,所有的類都是Class的對象,那么如何表示呢,可不可以通過如下方式呢:
Class c = new Class();
但是我們查看Class的源碼時,是這樣寫的:
private Class(ClassLoader loader) { classLoader = loader; }
可以看到構(gòu)造器是私有的,只有JVM可以創(chuàng)建Class的對象,因此不可以像普通類一樣new一個Class對象,雖然我們不能new一個Class對象,但是卻可以通過已有的類得到一個Class對象,共有三種方式,如下:
Class c1 = Code.class;
這說明任何一個類都有一個隱含的靜態(tài)成員變量class,這種方式是通過獲取類的靜態(tài)成員變量class得到的
Class c2 = code1.getClass();
code1是Code的一個對象,這種方式是通過一個類的對象的getClass()方法獲得的
Class c3 = Class.forName(“com.trigl.reflect.Code”);
這種方法是Class類調(diào)用forName方法,通過一個類的全量限定名獲得 ,這里,c1、c2、c3都是Class的對象,他們是完全一樣的,而且有個學名,叫做Code的類類型(class type)。 這里就讓人奇怪了,前面不是說Code是Class的對象嗎,而c1、c2、c3也是Class的對象,那么Code和c1、c2、c3不就一樣了嗎?為什么還叫Code什么類類型?這里不要糾結(jié)于它們是否相同,只要理解類類型是干什么的就好了,顧名思義,類類型就是類的類型,也就是描述一個類是什么,都有哪些東西,所以我們可以通過類類型知道一個類的屬性和方法,并且可以調(diào)用一個類的屬性和方法,這就是反射的基礎。
舉個簡單例子代碼:
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,那么我們可以通過這個Class干什么呢?
總結(jié)如下:
獲取成員方法Method
獲取成員變量Field
獲取構(gòu)造函數(shù)Constructor
下面來具體介紹
獲取成員方法信息
單獨獲取某一個方法是通過Class類的以下方法獲得的:
public Method getDeclaredMethod(String name, Class c){ }
如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
關(guān)于Linux服務器配置java環(huán)境遇到的問題小結(jié)
這篇文章主要介紹了關(guān)于Linux服務器配置java環(huán)境遇到的問題小結(jié),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12SpringBoot之那些注入不了的Spring占位符(${}表達式)問題
這篇文章主要介紹了SpringBoot之那些注入不了的Spring占位符(${}表達式)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04解決@Scheduled定時器使用@Thransactional事物問題
這篇文章主要介紹了解決@Scheduled定時器使用@Thransactional事物問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08Java實現(xiàn)二維數(shù)組和稀疏數(shù)組之間的轉(zhuǎn)換
本文主要介紹了Java 二維數(shù)組和稀疏數(shù)組轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-06-06ssm框架下web項目,web.xml配置文件的作用(詳解)
下面小編就為大家?guī)硪黄猻sm框架下web項目,web.xml配置文件的作用(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10