亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

darcrand / 2886人閱讀

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

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

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

什么是反射

萬物究其根,研究一樣新東西,首先我們需要了解它是什么,干什么用的。在運(yùn)行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為Java語言的反射機(jī)制。那么我們又能利用反射做什么呢?

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

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

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

那么本篇文章將圍繞者上面三個點(diǎn)來了解一下Java的反射機(jī)制。在開始之前,我們先來介紹一下一個類,這個類是我們在使用反射的過程中必不可少會使用到的一個類。

Class類

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

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

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

User user = new User();

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

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

利用反射分析類

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

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

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

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

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

3.獲取方法

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

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

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

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

利用反射查看對象

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

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

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

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()方法用來給屬性設(shè)置值。

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

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

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

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

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

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

API整理

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

1.Class類

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

2.Field類

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

3.Method類

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

4.Constructor類

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

5.AccessibleObject類

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

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

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

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

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/75633.html

相關(guān)文章

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

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

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

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

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

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

    baishancloud 評論0 收藏0
  • 一文帶你簡單了解Wi-Fi Direct

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

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

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

    saucxs 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<