Java反射機(jī)制

一、什么是JAVA的反射機(jī)制

  Java反射是Java被視為動(dòng)態(tài)(或準(zhǔn)動(dòng)態(tài))語言的一個(gè)關(guān)鍵性質(zhì)酌伊。這個(gè)機(jī)制允許程序在運(yùn)行時(shí)透過Reflection? APIs取得任何一個(gè)已知名稱的class的內(nèi)部信息漫萄,包括其modifiers(諸如public,?static? 等)、superclass(例如Object)盈匾、實(shí)現(xiàn)之interfaces(例如Cloneable)腾务,也包括fields和methods的所有信息,并可于運(yùn)行時(shí)改變fields內(nèi)容或喚起methods削饵。

  Java反射機(jī)制容許程序在運(yùn)行時(shí)加載岩瘦、探知、使用編譯期間完全未知的classes窿撬。

  換言之启昧,Java可以加載一個(gè)運(yùn)行時(shí)才得知名稱的class,獲得其完整結(jié)構(gòu)劈伴。

  二密末、JDK中提供的Reflection?API

  Java反射相關(guān)的API在包java.lang.reflect中,JDK?1.6.0的reflect包如下圖:

  #FormatImgID_0#

  Member接口該接口可以獲取有關(guān)類成員(域或者方法)后者構(gòu)造函數(shù)的信息跛璧。

  AccessibleObject類該類是域(field)對(duì)象严里、方法(method)對(duì)象、構(gòu)造函數(shù)(constructor)對(duì)象的基礎(chǔ)類追城。它提供了將反射的對(duì)象標(biāo)記為在使用時(shí)取消默認(rèn)? Java?語言訪問控制檢查的能力刹碾。

  Array類該類提供動(dòng)態(tài)地生成和訪問JAVA數(shù)組的方法。

  Constructor類提供一個(gè)類的構(gòu)造函數(shù)的信息以及訪問類的構(gòu)造函數(shù)的接口座柱。

  Field類提供一個(gè)類的域的信息以及訪問類的域的接口迷帜。

  Method類提供一個(gè)類的方法的信息以及訪問類的方法的接口物舒。

  Modifier類提供了?static?方法和常量,對(duì)類和成員訪問修飾符進(jìn)行解碼戏锹。

  Proxy類提供動(dòng)態(tài)地生成代理類和類實(shí)例的靜態(tài)方法冠胯。

  三、JAVA反射機(jī)制提供了什么功能

  Java反射機(jī)制提供如下功能:

  在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類

  在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象

  在運(yùn)行時(shí)判段任意一個(gè)類所具有的成員變量和方法

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

  在運(yùn)行時(shí)創(chuàng)建新類對(duì)象

  在使用Java的反射功能時(shí)景用,基本首先都要獲取類的Class對(duì)象涵叮,再通過Class對(duì)象獲取其他的對(duì)象。

  這里首先定義用于測(cè)試的類:

  +?View?Code

  1伞插、獲取類的Class對(duì)象

  Class?類的實(shí)例表示正在運(yùn)行的?Java?應(yīng)用程序中的類和接口割粮。獲取類的Class對(duì)象有多種方式:

  調(diào)用getClassBoolean?var1?=?true;

  Class?classType2?=?var1.getClass();

  System.out.println(classType2);

  輸出:class?java.lang.Boolean

  運(yùn)用.class?語法Class?classType4?=?Boolean.class;

  System.out.println(classType4);

  輸出:class?java.lang.Boolean

  運(yùn)用static?method?Class.forName()Class?classType5?=? Class.forName("java.lang.Boolean");

  System.out.println(classType5);

  輸出:class?java.lang.Boolean

  運(yùn)用primitive?wrapper?classes的TYPE?語法

  這里返回的是原生類型,和Boolean.class返回的不同Class?classType3?=?Boolean.TYPE;

  System.out.println(classType3);

  輸出:boolean

  2媚污、獲取類的Fields

  可以通過反射機(jī)制得到某個(gè)類的某個(gè)屬性舀瓢,然后改變對(duì)應(yīng)于這個(gè)類的某個(gè)實(shí)例的該屬性值。JAVA?的Class類提供了幾個(gè)方法獲取類的屬性耗美。

  public?FieldgetField(String?name)返回一個(gè)?Field?對(duì)象京髓,它反映此?Class? 對(duì)象所表示的類或接口的指定公共成員字段

  public?Field[]?getFields()返回一個(gè)包含某些?Field?對(duì)象的數(shù)組,這些對(duì)象反映此?Class? 對(duì)象所表示的類或接口的所有可訪問公共字段

  public?FieldgetDeclaredField(Stringname)返回一個(gè)?Field?對(duì)象商架,該對(duì)象反映此?Class? 對(duì)象所表示的類或接口的指定已聲明字段

  public?Field[]?getDeclaredFields()返回?Field?對(duì)象的一個(gè)數(shù)組堰怨,這些對(duì)象反映此?Class? 對(duì)象所表示的類或接口所聲明的所有字段

  +?View?Code

  輸出:

  public?int?com.quincy.ExtendType.pubIntExtendField

  public?java.lang.String?com.quincy.ExtendType.pubStringExtendField

  public?int?com.quincy.Type.pubIntField

  public?java.lang.String?com.quincy.Type.pubStringField

  public?int?com.quincy.ExtendType.pubIntExtendField

  public?java.lang.String?com.quincy.ExtendType.pubStringExtendField

  private?int?com.quincy.ExtendType.prvIntExtendField

  可見getFields和getDeclaredFields區(qū)別:

  getFields返回的是申明為public的屬性,包括父類中定義蛇摸,

  getDeclaredFields返回的是指定類定義的所有定義的屬性备图,不包括父類的。

  3赶袄、獲取類的Method

  通過反射機(jī)制得到某個(gè)類的某個(gè)方法揽涮,然后調(diào)用對(duì)應(yīng)于這個(gè)類的某個(gè)實(shí)例的該方法

  Class類提供了幾個(gè)方法獲取類的方法。

  public?MethodgetMethod(String?name,?Class...?parameterTypes)返回一個(gè)?Method? 對(duì)象饿肺,它反映此?Class?對(duì)象所表示的類或接口的指定公共成員方法

  public?Method[]?getMethods()返回一個(gè)包含某些?Method?對(duì)象的數(shù)組蒋困,這些對(duì)象反映此?Class? 對(duì)象所表示的類或接口(包括那些由該類或接口聲明的以及從超類和超接口繼承的那些的類或接口)的公共?member?方法

  public?MethodgetDeclaredMethod(String?name,Class...?parameterTypes)返回一個(gè)? Method?對(duì)象,該對(duì)象反映此?Class?對(duì)象所表示的類或接口的指定已聲明方法

  public?Method[]?getDeclaredMethods()返回?Method?對(duì)象的一個(gè)數(shù)組敬辣,這些對(duì)象反映此?Class? 對(duì)象表示的類或接口聲明的所有方法雪标,包括公共、保護(hù)溉跃、默認(rèn)(包)訪問和私有方法汰聋,但不包括繼承的方法

  +?View?Code

  輸出:

  public?void?com.quincy.ExtendType.setIntExtendField(int)

  public?int?com.quincy.ExtendType.getIntExtendField()

  public?void?com.quincy.Type.setIntField(int)

  public?int?com.quincy.Type.getIntField()

  public?final?native?void?java.lang.Object.wait(long)?throws? java.lang.InterruptedException

  public?final?void?java.lang.Object.wait()?throws? java.lang.InterruptedException

  public?final?void?java.lang.Object.wait(long,int)?throws? java.lang.InterruptedException

  public?boolean?java.lang.Object.equals(java.lang.Object)

  public?java.lang.String?java.lang.Object.toString()

  public?native?int?java.lang.Object.hashCode()

  public?final?native?java.lang.Class?java.lang.Object.getClass()

  public?final?native?void?java.lang.Object.notify()

  public?final?native?void?java.lang.Object.notifyAll()

  private?void?com.quincy.ExtendType.Log(java.lang.String)

  public?void?com.quincy.ExtendType.setIntExtendField(int)

  public?int?com.quincy.ExtendType.getIntExtendField()

  4、獲取類的Constructor

  通過反射機(jī)制得到某個(gè)類的構(gòu)造器喊积,然后調(diào)用該構(gòu)造器創(chuàng)建該類的一個(gè)實(shí)例

  Class類提供了幾個(gè)方法獲取類的構(gòu)造器烹困。

  public?Constructor?getConstructor(Class...?parameterTypes)返回一個(gè)? Constructor?對(duì)象,它反映此?Class?對(duì)象所表示的類的指定公共構(gòu)造方法

  public?Constructor[]?getConstructors()返回一個(gè)包含某些?Constructor?對(duì)象的數(shù)組乾吻,這些對(duì)象反映此? Class?對(duì)象所表示的類的所有公共構(gòu)造方法

  public?Constructor?getDeclaredConstructor(Class...? parameterTypes)返回一個(gè)?Constructor?對(duì)象髓梅,該對(duì)象反映此?Class?對(duì)象所表示的類或接口的指定構(gòu)造方法

  public?Constructor[]?getDeclaredConstructors()返回?Constructor? 對(duì)象的一個(gè)數(shù)組拟蜻,這些對(duì)象反映此?Class?對(duì)象表示的類聲明的所有構(gòu)造方法。它們是公共枯饿、保護(hù)酝锅、默認(rèn)(包)訪問和私有構(gòu)造方法

  +?View?Code

  5、新建類的實(shí)例

  通過反射機(jī)制創(chuàng)建新類的實(shí)例奢方,有幾種方法可以創(chuàng)建

  調(diào)用無自變量ctor1搔扁、調(diào)用類的Class對(duì)象的newInstance方法,該方法會(huì)調(diào)用對(duì)象的默認(rèn)構(gòu)造器蟋字,如果沒有默認(rèn)構(gòu)造器稿蹲,會(huì)調(diào)用失敗.

  Class?classType?=?ExtendType.class;

  Object?inst?=?classType.newInstance();

  System.out.println(inst);

  輸出:

  Type:Default?Constructor

  ExtendType:Default?Constructor

  com.quincy.ExtendType@d80be3

  2、調(diào)用默認(rèn)Constructor對(duì)象的newInstance方法

  Class?classType?=?ExtendType.class;

  Constructor?constructor1?=?classType.getConstructor();

  Object?inst?=?constructor1.newInstance();

  System.out.println(inst);

  輸出:

  Type:Default?Constructor

  ExtendType:Default?Constructor

  com.quincy.ExtendType@1006d75

  調(diào)用帶參數(shù)ctor3鹊奖、調(diào)用帶參數(shù)Constructor對(duì)象的newInstance方法

  Constructor?constructor2?=

  classType.getDeclaredConstructor(int.class,?String.class);

  Object?inst?=?constructor2.newInstance(1,?"123");

  System.out.println(inst);

  輸出:

  Type:Default?Constructor

  ExtendType:Constructor?with?parameters

  com.quincy.ExtendType@15e83f9

  6苛聘、調(diào)用類的函數(shù)

  通過反射獲取類Method對(duì)象,調(diào)用Field的Invoke方法調(diào)用函數(shù)忠聚。

  +?View?Code

  7设哗、設(shè)置/獲取類的屬性值

  通過反射獲取類的Field對(duì)象,調(diào)用Field方法設(shè)置或獲取值

  +?View?Code

  +?View?Code

  四两蟀、動(dòng)態(tài)創(chuàng)建代理類

  代理模式:代理模式的作用=為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問网梢。

  代理模式的角色:

  抽象角色:聲明真實(shí)對(duì)象和代理對(duì)象的共同接口

  代理角色:代理角色內(nèi)部包含有真實(shí)對(duì)象的引用,從而可以操作真實(shí)對(duì)象赂毯。

  真實(shí)角色:代理角色所代表的真實(shí)對(duì)象战虏,是我們最終要引用的對(duì)象。

  動(dòng)態(tài)代理:

  java.lang.reflect.ProxyProxy?提供用于創(chuàng)建動(dòng)態(tài)代理類和實(shí)例的靜態(tài)方法欢瞪,它還是由這些方法創(chuàng)建的所有動(dòng)態(tài)代理類的超類

  InvocationHandler是代理實(shí)例的調(diào)用處理程序? 實(shí)現(xiàn)的接口,每個(gè)代理實(shí)例都具有一個(gè)關(guān)聯(lián)的調(diào)用處理程序徐裸。對(duì)代理實(shí)例調(diào)用方法時(shí)遣鼓,將對(duì)方法調(diào)用進(jìn)行編碼并將其指派到它的調(diào)用處理程序的?invoke?方法。

  動(dòng)態(tài)Proxy是這樣的一種類:

  它是在運(yùn)行生成的類重贺,在生成時(shí)你必須提供一組Interface給它骑祟,然后該class就宣稱它實(shí)現(xiàn)了這些interface。你可以把該class的實(shí)例當(dāng)作這些interface中的任何一個(gè)來用气笙。當(dāng)然次企,這個(gè)Dynamic? Proxy其實(shí)就是一個(gè)Proxy,它不會(huì)替你作實(shí)質(zhì)性的工作潜圃,在生成它的實(shí)例時(shí)你必須提供一個(gè)handler缸棵,由它接管實(shí)際的工作。

  在使用動(dòng)態(tài)代理類時(shí)谭期,我們必須實(shí)現(xiàn)InvocationHandler接口

  步驟:

  1堵第、定義抽象角色

  public?interface?Subject?{

  public?void?Request();

  }

  2吧凉、定義真實(shí)角色

  public?class?RealSubject?implements?Subject?{

  @Override

  public?void?Request()?{

  //?TODO?Auto-generated?method?stub

  System.out.println("RealSubject");

  }

  }

  3、定義代理角色

  public?class?DynamicSubject?implements?InvocationHandler?{

  private?Object?sub;

  public?DynamicSubject(Object?obj){

  this.sub?=?obj;

  }

  @Override

  public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)

  throws?Throwable?{

  //?TODO?Auto-generated?method?stub

  System.out.println("Method:"+?method?+?",Args:"?+?args);

  method.invoke(sub,?args);

  return?null;

  }

  }

  4踏志、通過Proxy.newProxyInstance構(gòu)建代理對(duì)象

  RealSubject?realSub?=?new?RealSubject();

  InvocationHandler?handler?=?new?DynamicSubject(realSub);

  Class?classType?=?handler.getClass();

  Subject?sub?=? (Subject)Proxy.newProxyInstance(classType.getClassLoader(),

  realSub.getClass().getInterfaces(),?handler);

  System.out.println(sub.getClass());

  5阀捅、通過調(diào)用代理對(duì)象的方法去調(diào)用真實(shí)角色的方法。

  sub.Request();

  輸出:

  class?$Proxy0?新建的代理對(duì)象针余,它實(shí)現(xiàn)指定的接口

  Method:public?abstract?void?DynamicProxy.Subject.Request(),Args:null

  RealSubject?調(diào)用的真實(shí)對(duì)象的方法

Java交流裙:109--1181--875

java-數(shù)據(jù)類型

http://www.makeru.com.cn/live/1394_203.html?s=156461

常用工具類

http://www.makeru.com.cn/live/1394_253.html?s=156461

javaweb后端開發(fā)案例

http://www.makeru.com.cn/live/1394_366.html?s=156461

http://www.makeru.com.cn/live/1394_365.html?s=156461

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饲鄙,一起剝皮案震驚了整個(gè)濱河市吃衅,隨后出現(xiàn)的幾起案子歹垫,更是在濱河造成了極大的恐慌,老刑警劉巖胡陪,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摸柄,死亡現(xiàn)場(chǎng)離奇詭異颤练,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)驱负,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門嗦玖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人跃脊,你說我怎么就攤上這事宇挫。” “怎么了酪术?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵器瘪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我绘雁,道長(zhǎng)橡疼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任庐舟,我火速辦了婚禮欣除,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挪略。我一直安慰自己历帚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布杠娱。 她就那樣靜靜地躺著挽牢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摊求。 梳的紋絲不亂的頭發(fā)上禽拔,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼奏赘。 笑死寥闪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的磨淌。 我是一名探鬼主播疲憋,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼梁只!你這毒婦竟也來了缚柳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤搪锣,失蹤者是張志新(化名)和其女友劉穎秋忙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體构舟,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灰追,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狗超。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弹澎。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖努咐,靈堂內(nèi)的尸體忽然破棺而出苦蒿,到底是詐尸還是另有隱情,我是刑警寧澤渗稍,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布佩迟,位于F島的核電站,受9級(jí)特大地震影響竿屹,放射性物質(zhì)發(fā)生泄漏报强。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一拱燃、第九天 我趴在偏房一處隱蔽的房頂上張望秉溉。 院中可真熱鬧,春花似錦扼雏、人聲如沸坚嗜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至诱建,卻和暖如春蝴蜓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工茎匠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留格仲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓诵冒,卻偏偏與公主長(zhǎng)得像凯肋,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汽馋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350