成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

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

darcrand / 2887人閱讀

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

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

上周上班的時(shí)候解決一個(gè)需求,需要將一批數(shù)據(jù)導(dǎo)出到Excel。本來(lái)公司的中間件組已經(jīng)封裝好了使用POI生成Excel的工具方法,但是無(wú)奈產(chǎn)品的需求里面有個(gè)合并單元格的要求,工具類(lèi)中找了半天也沒(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è)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱(chēng)為Java語(yǔ)言的反射機(jī)制。那么我們又能利用反射做什么呢?

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

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

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

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

Class類(lèi)

在運(yùn)行時(shí),Java運(yùn)行時(shí)系統(tǒng)會(huì)為每一個(gè)對(duì)象都維護(hù)一個(gè)標(biāo)識(shí)這個(gè)對(duì)象類(lèi)型的信息,而保存這些信息的類(lèi)型就是Class類(lèi)。我們可以通過(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è)類(lèi)型,就像下面這樣:

User user = new User();

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

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

利用反射分析類(lèi)

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

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

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

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

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

3.獲取方法

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

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

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

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

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

有些時(shí)候呢,我們可能也需要反射去獲取對(duì)象中屬性的值,比如說(shuō)在導(dǎo)出Excel的時(shí)候,我們只知道列所對(duì)應(yīng)屬性的字段名稱(chē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類(lèi)中提供的get(Object obj)方法來(lái)獲取屬性的值,對(duì)于基礎(chǔ)類(lèi)型還提供了特定的get方法,比如getDouble()。但是如果上面的userName是個(gè)私有屬性的話(huà),get()方法肯定會(huì)拋出IllegalAccessException的異常。這是時(shí)候我們需要使用setAccessible()方法覆蓋安全管理器的訪(fǎng)問(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類(lèi)中都有提供。與get()方法呼應(yīng),Field還提供了set()方法用來(lái)給屬性設(shè)置值。

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

在Method類(lèi)中提供了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類(lèi)中的sayHello()方法吧。

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

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

API整理

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

1.Class類(lèi)

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

2.Field類(lèi)

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

3.Method類(lèi)

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

4.Constructor類(lèi)

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

5.AccessibleObject類(lèi)

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

這篇文章主要和大家一起了解了一下Java的反射機(jī)制,以及在反射包下Field、MethodConstructor三個(gè)類(lèi)所提供的api。在利用反射分析類(lèi)小節(jié)中,我提到了使用反射打印類(lèi)的完整信息,具體的實(shí)現(xiàn)代碼點(diǎn)擊這里獲取。希望這篇文章能夠?qū)Υ蠹矣兴鶐椭?。最后,如果你喜歡這篇文章的話(huà)歡迎在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://m.hztianpu.com/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í)慣 枚舉類(lèi)型嵌套枚舉類(lèi)型實(shí)例----交通信號(hào)燈枚舉類(lèi)型的方法帶參數(shù)的枚舉類(lèi)型的枚舉常量? 博主的話(huà) Java養(yǎng)成計(jì)劃(打卡第18天) JAVA SE(夯實(shí)基...

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

    摘要:本文是作者自己對(duì)中線(xiàn)程的狀態(tài)線(xiàn)程間協(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)這些容器需要額外的工具,這稱(chēng)之為容器編排。的核心優(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)目正為了稱(chē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ò)程。用戶(hù)可以按下任一設(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)論

閱讀需要支付1元查看
<