成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

一文帶你了解Java反射機(jī)制

darcrand / 2835人閱讀

摘要:在的反射包中提供了三個(gè)類以及來(lái)分別描述屬性方法和構(gòu)造器。獲取構(gòu)造器獲取方法可以看到我們可以通過(guò)一個(gè)類的對(duì)象很輕松的獲取他的屬性構(gòu)造器以及方法信息。返冋一個(gè)用于描述構(gòu)造器名的字符串。

想要獲取更多文章可以訪問(wèn)我的博客?-?代碼無(wú)止境。

上周上班的時(shí)候解決一個(gè)需求,需要將一批數(shù)據(jù)導(dǎo)出到Excel。本來(lái)公司的中間件組已經(jīng)封裝好了使用POI生成Excel的工具方法,但是無(wú)奈產(chǎn)品的需求里面有個(gè)合并單元格的要求,工具類中找了半天也沒(méi)發(fā)現(xiàn)適用的方法,就只能自己擼起袖子干了。導(dǎo)出Excel的工具方法會(huì)少不了使用反射,但是反射這東西對(duì)于我這種寫(xiě)業(yè)務(wù)代碼的人來(lái)說(shuō)接觸比較少,所以就惡補(bǔ)了一下,寫(xiě)下這篇文章記錄一下。

什么是反射

萬(wàn)物究其根,研究一樣新東西,首先我們需要了解它是什么,干什么用的。在運(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ī)制。那么我們又能利用反射做什么呢?

在運(yùn)行時(shí)分析類。

在運(yùn)行時(shí)查看對(duì)象,我們還可以利用反射編寫(xiě)一個(gè)toString方法供所有類使用。

利用Method對(duì)象,在運(yùn)行時(shí)任意調(diào)用一個(gè)對(duì)象的方法。

那么本篇文章將圍繞者上面三個(gè)點(diǎn)來(lái)了解一下Java的反射機(jī)制。在開(kāi)始之前,我們先來(lái)介紹一下一個(gè)類,這個(gè)類是我們?cè)谑褂梅瓷涞倪^(guò)程中必不可少會(huì)使用到的一個(gè)類。

Class類

在運(yùn)行時(shí),Java運(yùn)行時(shí)系統(tǒng)會(huì)為每一個(gè)對(duì)象都維護(hù)一個(gè)標(biāo)識(shí)這個(gè)對(duì)象類型的信息,而保存這些信息的類型就是Class類。我們可以通過(guò)對(duì)象的getClass()方法來(lái)獲取該對(duì)象對(duì)于的Class對(duì)象,就像下面這樣。

User user = new User();
Class c = user.getClass();

這個(gè)世界上的任何東西都有它存在的意義,那么我們可以用Class對(duì)象來(lái)干什么呢?我們最常使用Class來(lái)判斷一個(gè)對(duì)象是不是屬于某個(gè)類型,就像下面這樣:

User user = new User();

if (user.getClass() == User.class) {
    System.out.println("user is User");
}

當(dāng)然我們也經(jīng)常會(huì)使用Class類的getName()方法來(lái)獲取某個(gè)類的名稱。有寫(xiě)時(shí)候,我們還會(huì)利用它的newInstance()方法來(lái)獲取某個(gè)類型的實(shí)例(當(dāng)這類沒(méi)有提供共有的構(gòu)造方法時(shí))。

利用反射分析類

分析一個(gè)類,無(wú)外乎就是查看這個(gè)類中的屬性、方法以及其構(gòu)造方法了。在Java的反射包中提供了三個(gè)類Field、Method以及Constructor來(lái)分別描述屬性、方法和構(gòu)造器。
下面我們就分別來(lái)看下,我們是如何通過(guò)反射機(jī)制來(lái)獲取一個(gè)類的這些信息的。
1.獲取屬性

User user = new User();
Class cl = user.getClass();
Field[] fields1 = cl.getFields();
Field[] fields2 = cl.getDeclaredFields();

可以看到我們可以利用getFields()getDeclaredFields()兩個(gè)方法來(lái)獲取類中的屬性列表,那么這兩個(gè)方法有什么區(qū)別呢?區(qū)別就是前者只會(huì)返回類的共有成員信息,而后者這會(huì)返回類中所有的成員信息包括公有的、私有的、受保護(hù)的,但是不包括父類的成員信息。

2.獲取構(gòu)造器

Constructor[] constructors1 = cl.getConstructors();
Constructor[] constructors2 = cl.getDeclaredConstructors();

3.獲取方法

Method[] methods1 = cl.getMethods();
Method[] methods2 = cl.getDeclaredMethods();

可以看到我們可以通過(guò)一個(gè)類的Class對(duì)象很輕松的獲取他的屬性、構(gòu)造器以及方法信息。但是在Field、Constructor以及Method中又分別提供了哪些api呢?下面我們就一起來(lái)看下。

1.getName()方法,用來(lái)獲取對(duì)應(yīng)的名稱。同時(shí)存在于Field、Constructor以及Method類中。
2.getModifiers()方法來(lái)獲取前面的修飾符(public等),但是getModifiers()返回的是一個(gè)int值,我們可以通過(guò)Modifier.toString(int i)將其轉(zhuǎn)換成對(duì)應(yīng)的字符串。也同樣同時(shí)存在于Field、Constructor以及Method類中。
3.getParameterTypes()方法,用來(lái)獲取方法的參數(shù)類型數(shù)組。存在于Constructor以及Method類中
4.getReturnType()方法,用來(lái)獲取方法的返回類型。只存在于Method類中

有了這些api,我們就擁有了在運(yùn)行時(shí)分析一個(gè)類的能力,我們可以通過(guò)一個(gè)簡(jiǎn)單的小例子來(lái)實(shí)踐一下,我們可以編寫(xiě)一個(gè)方法來(lái)輸出一個(gè)類的完整信息,具體的實(shí)現(xiàn)會(huì)在文末給出,大家可以先自己嘗試一下。

利用反射查看對(duì)象

有些時(shí)候呢,我們可能也需要反射去獲取對(duì)象中屬性的值,比如說(shuō)在導(dǎo)出Excel的時(shí)候,我們只知道列所對(duì)應(yīng)屬性的字段名稱,然后我們需要通過(guò)反射獲取它的值,然后把它寫(xiě)到Excel中。那么這節(jié)內(nèi)容就一起來(lái)看下如何利用Java的反射機(jī)制來(lái)分析對(duì)象。

User user = new User(1,"itweknow");
Class cl = user.getClass();
Field userName = cl.getDeclaredField("userName");
Object value = userName.get(user);

就像上面的代碼一樣,我們可以使用Field類中提供的get(Object obj)方法來(lái)獲取屬性的值,對(duì)于基礎(chǔ)類型還提供了特定的get方法,比如getDouble()。但是如果上面的userName是個(gè)私有屬性的話,get()方法肯定會(huì)拋出IllegalAccessException的異常。這是時(shí)候我們需要使用setAccessible()方法覆蓋安全管理器的訪問(wèn)控制。

User user = new User(1,"itweknow");
Class cl = user.getClass();
Field userName = cl.getDeclaredField("userName");
userName.setAccessible(true);
Object value = userName.get(user);

setAccessible()方法在Field、Method、Constructor類中都有提供。與get()方法呼應(yīng),Field還提供了set()方法用來(lái)給屬性設(shè)置值。

利用反射調(diào)用任何方法

在Method類中提供了invoke()方法來(lái)調(diào)用,當(dāng)前Method對(duì)象所包裝的方法。invoke()方法的定義如下:

Object invoke(Object obj, Object... args)

第一個(gè)參數(shù)是調(diào)用這個(gè)方法的對(duì)象,第二個(gè)參數(shù)是該方法的參數(shù),是一個(gè)數(shù)組的形式。下面我們就來(lái)看下如何利用反射來(lái)調(diào)用User類中的sayHello()方法吧。

Method sayHelloMethod = cl.getDeclaredMethod("sayHello", String.class);
sayHelloMethod.setAccessible(true);
sayHelloMethod.invoke(user, "Reflect");

看上面的代碼我們通過(guò)getDeclaredMethod()方法來(lái)獲取了一個(gè)名為sayHello的私有方法(PS:如果是公有方法的話直接使用getMethod()方法就可以了),同樣對(duì)于私有方法,我們需要修改它的訪問(wèn)控制才能順利調(diào)用。

API整理

上面的章節(jié)中提到了不少Java反射機(jī)制中提供的Api,下面是我整理的一些常用的反射Api,大家可以參考一下。

1.Class類

Api 描述
forName() 返回指定類名的Class對(duì)象
newInstance() 返回一個(gè)這個(gè)類的新實(shí)例
getFields() 返回這個(gè)類所有的公有屬性
getDeclaredField() 返回這個(gè)類所有的屬性(包含公有、私有、受保護(hù))
getMethods() 返回這個(gè)類下所有的共有方法
getDeclaredMethods() 返回這個(gè)類所有的方法(包含公有、私有、受保護(hù))
getConstructors() 返回這個(gè)類所有公有的構(gòu)造器
getDeclaredConstructors() 返回這個(gè)類所有的構(gòu)造器(包含公有、私有、受保護(hù))
getField() & getDeclaredField() 返回這個(gè)類中指定名稱的屬性
getMethod() & getDeclaredMethod() 返回指定名稱和參數(shù)的方法
cl.getConstructor() & cl.getDeclaredConstructor() 獲取指定參數(shù)的構(gòu)造器

2.Field類

Api 描述
getModifiers() 返回一個(gè)用于描述屬性的修飾符的整型數(shù)值。使用 Modifier類中的toString()方法將其轉(zhuǎn)為字符串。
getName() 返冋一個(gè)用于描述屬性名的字符串。

3.Method類

Api 描述
getModifiers() 返回一個(gè)用于描述方法的修飾符的整型數(shù)值。使用 Modifier類中的toString()方法將其轉(zhuǎn)為字符串。
getName() 返冋一個(gè)用于描述方法名的字符串。
getParameterTypes() 返回一個(gè)用于描述參數(shù)類型的Class對(duì)象數(shù)組。
getReturnType() 返回一個(gè)用于描述返H類型的Class對(duì)象。
invoke() 調(diào)用這個(gè)對(duì)象所描述的方法, 傳遞給定參數(shù),并返回方法的返回值。

4.Constructor類

Api 描述
getModifiers() 返回一個(gè)用于描述構(gòu)造器的修飾符的整型數(shù)值。使用 Modifier類中的toString()方法將其轉(zhuǎn)為字符串。
getName() 返冋一個(gè)用于描述構(gòu)造器名的字符串。
getParameterTypes() 返回一個(gè)用于描述參數(shù)類型的Class對(duì)象數(shù)組。

5.AccessibleObject類

Api 描述
setAccessible(boolean flag) 為反射對(duì)象設(shè)置可訪問(wèn)標(biāo)志。flag 為 true 表明屏蔽 Java 語(yǔ)言的訪問(wèn)檢查,使得對(duì)象的私有屬性也可以被査詢和設(shè)置。
isAccessible() 返回反射對(duì)象的可訪問(wèn)標(biāo)志的值。
結(jié)束語(yǔ)

這篇文章主要和大家一起了解了一下Java的反射機(jī)制,以及在反射包下Field、MethodConstructor三個(gè)類所提供的api。在利用反射分析類小節(jié)中,我提到了使用反射打印類的完整信息,具體的實(shí)現(xiàn)代碼點(diǎn)擊這里獲取。希望這篇文章能夠?qū)Υ蠹矣兴鶐椭?。最后,如果你喜歡這篇文章的話歡迎在Github源碼項(xiàng)目點(diǎn)個(gè)Star。

PS:學(xué)習(xí)不止,碼不停蹄!如果您喜歡我的文章,就關(guān)注我吧!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75633.html

相關(guān)文章

  • ?Java枚舉實(shí)例---交通燈,一文帶你深入理解枚舉,了解融會(huì)貫通JAVA SE所該具備的能力【Ja

    Java學(xué)習(xí)打卡:第十八天 內(nèi)容導(dǎo)航 Java學(xué)習(xí)打卡:第十八天內(nèi)容管理基礎(chǔ)問(wèn)題(一定不要忘記)Java對(duì)象清除機(jī)制(垃圾處理機(jī)制)什么樣的對(duì)象是垃圾呢?那一個(gè)對(duì)象成為垃圾有哪幾種情況?一個(gè)良好習(xí)慣 枚舉類型嵌套枚舉類型實(shí)例----交通信號(hào)燈枚舉類型的方法帶參數(shù)的枚舉類型的枚舉常量? 博主的話 Java養(yǎng)成計(jì)劃(打卡第18天) JAVA SE(夯實(shí)基...

    ChanceWong 評(píng)論0 收藏0
  • Java相關(guān)

    摘要:本文是作者自己對(duì)中線程的狀態(tài)線程間協(xié)作相關(guān)使用的理解與總結(jié),不對(duì)之處,望指出,共勉。當(dāng)中的的數(shù)目而不是已占用的位置數(shù)大于集合番一文通版集合番一文通版垃圾回收機(jī)制講得很透徹,深入淺出。 一小時(shí)搞明白自定義注解 Annotation(注解)就是 Java 提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法。Annotion(注解) 是一個(gè)接口,程序可以通過(guò)...

    wangtdgoodluck 評(píng)論0 收藏0
  • 一文帶你重新認(rèn)識(shí) Docker 與 Kubernetes

    摘要:公司始于名為的平臺(tái)即服務(wù)供應(yīng)商??缍鄠€(gè)機(jī)器之間協(xié)調(diào)這些容器需要額外的工具,這稱之為容器編排。的核心優(yōu)勢(shì)是為應(yīng)用程序開(kāi)發(fā)人員提供了用于編排無(wú)狀態(tài)容器的強(qiáng)大工具。有無(wú)數(shù)的文章都在討論和比較Docker、Kubernetes 以及Mesos。如果你是初學(xué)者,那么你可能會(huì)認(rèn)為這三個(gè)開(kāi)源項(xiàng)目正為了稱霸容器界而殊死搏斗。雖然這三種技術(shù)都使得使用容器部署、管理和伸縮應(yīng)用成為可能,但實(shí)際上它們各自解決了不同...

    baishancloud 評(píng)論0 收藏0
  • 一文帶你簡(jiǎn)單了解Wi-Fi Direct

    摘要:最大傳輸距離是米,最大傳輸速度為,支持與頻段??梢詫?shí)現(xiàn)一對(duì)一,以及一對(duì)多。簡(jiǎn)單而安全的連接設(shè)備采用簡(jiǎn)化了在設(shè)備之間創(chuàng)建安全連接的過(guò)程。用戶可以按下任一設(shè)備上的按鈕,也可以輸入碼即設(shè)備顯示的碼,輕松創(chuàng)建安全連接。 ...

    FWHeart 評(píng)論0 收藏0
  • 推薦:7 月份值得一看的 Java 技術(shù)干貨!

    摘要:月底了,又到了我們總結(jié)這一個(gè)月技術(shù)干貨的時(shí)候了,又到了我們給粉絲免費(fèi)送書(shū)的日子了。 月底了,又到了我們總結(jié)這一個(gè)月 Java 技術(shù)干貨的時(shí)候了,又到了我們給粉絲免費(fèi)送書(shū)的日子了。 7 月份干貨總結(jié) Oracle 發(fā)布了一個(gè)全棧虛擬機(jī) GraalVM 一文帶你深入拆解 Java 虛擬機(jī) 圖文帶你了解 8 大排序算法 Spring Boot 2.x 新特性總結(jié)及遷移指南 Spring B...

    saucxs 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<