日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

Java反射(Reflection)

發(fā)布時(shí)間:2023/12/2 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java反射(Reflection) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基本概念

  在Java運(yùn)行時(shí)環(huán)境中,對(duì)于任意一個(gè)類,能否知道這個(gè)類有哪些屬性和方法?對(duì)于任意一個(gè)對(duì)象,能否調(diào)用它的任意一個(gè)方法?

  答案是肯定的。

  這種動(dòng)態(tài)獲取類的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能來自于Java語言的反射(Reflection)機(jī)制

  

  Java反射機(jī)制主要提供了以下功能:

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

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

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

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

? ? ? 5.在運(yùn)行時(shí)設(shè)定任意一個(gè)對(duì)象的屬性值

  Reflection是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 (例如Serializable)、也包括其constuctors,fields和methods的所有信息,并可于運(yùn)行時(shí)改變fields內(nèi)容或調(diào)用methods。

?

動(dòng)態(tài)語言

  動(dòng)態(tài)語言的定義“程序運(yùn)行時(shí),允許改變程序結(jié)構(gòu)或者變量類型,這種語言稱為動(dòng)態(tài)語言”。

  從這個(gè)觀點(diǎn)看,Perl,Python,Ruby是動(dòng)態(tài)語言,C++,Java,C#不是動(dòng)態(tài)語言。

  盡管在這樣的定義與分類下Java不是動(dòng)態(tài)語言,它卻有著一個(gè)非常突出的動(dòng)態(tài)相關(guān)機(jī)制:Reflection。這個(gè)字的意思是:反射、映像、倒影,用在Java身上指的是我們可以于運(yùn)行時(shí)加載、探知、使用編譯期間完全未知的classes。

  換句話說,Java程序可以加載一個(gè)運(yùn)行時(shí)才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對(duì)象實(shí)體、或?qū)ζ鋐ields設(shè)值、或喚起其methods。

  這種“看透”class的能力(the ability of the program to examine itself)被稱為introspection(內(nèi)省、內(nèi)觀、反省)。Reflectionintrospection是常被并提的兩個(gè)術(shù)語。

?

Java Reflection API簡(jiǎn)介

  在JDK中,主要由以下類來實(shí)現(xiàn)Java反射機(jī)制,這些類(除了第一個(gè))都位于java.lang.reflect包中

  Class:代表一個(gè)類,位于java.lang包下。

  Field:代表類的成員變量(成員變量也稱為類的屬性)。

  Method:代表類的方法。

  Constructor:代表類的構(gòu)造方法。

  Array:提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法。

?

Class對(duì)象

  要想使用反射,首先需要獲得待操作的類所對(duì)應(yīng)的Class對(duì)象。

  Java中,無論生成某個(gè)類的多少個(gè)對(duì)象,這些對(duì)象都會(huì)對(duì)應(yīng)于同一個(gè)Class對(duì)象。

  這個(gè)Class對(duì)象是由JVM生成的,通過它能夠獲悉整個(gè)類的結(jié)構(gòu)。

?

  常用的獲取Class對(duì)象的3種方式:

  1.使用Class類的靜態(tài)方法例如:  

Class.forName("java.lang.String");

?

  2.使用類的.class語法如:

String.class;

?

  3.使用對(duì)象的getClass()方法。如:

String str = "aa"; Class<?> classType1 = str.getClass();

?

  getClass()方法定義在Object類中,不是靜態(tài)方法,需要通過對(duì)象來調(diào)用,并且它聲明為final,表明不能被子類所覆寫。

  直接print所獲得的Class對(duì)象classType會(huì)輸出:

    class 完整類名

  如果調(diào)用該Class對(duì)象的getName()方法,則輸出完整類名,不加class。

?

例程1:獲取方法

  例程DumpMethods類演示了Reflection API的基本作用,它讀取命令行參數(shù)指定的類名,然后打印這個(gè)類所具有的方法信息。 

import java.lang.reflect.Method;public class DumpMethods {public static void main(String[] args) throws Exception //在方法后加上這句,異常就消失了{(lán)//獲得字符串所標(biāo)識(shí)的類的class對(duì)象Class<?> classType = Class.forName("java.lang.String");//在此處傳入字符串指定類名,所以參數(shù)獲取可以是一個(gè)運(yùn)行期的行為,可以用args[0]//返回class對(duì)象所對(duì)應(yīng)的類或接口中,所聲明的所有方法的數(shù)組(包括私有方法)Method[] methods = classType.getDeclaredMethods();//遍歷輸出所有方法聲明for(Method method : methods){System.out.println(method);}}}

?

?

例程2:通過反射調(diào)用方法

  通過反射調(diào)用方法。詳情見代碼及注釋:

?

import java.lang.reflect.Method;public class InvokeTester {public int add(int param1, int param2){return param1 + param2;}public String echo(String message){return "Hello: " + message;}public static void main(String[] args) throws Exception{// 以前的常規(guī)執(zhí)行手段InvokeTester tester = new InvokeTester();System.out.println(tester.add(1, 2));System.out.println(tester.echo("Tom"));System.out.println("---------------------------");// 通過反射的方式// 第一步,獲取Class對(duì)象// 前面用的方法是:Class.forName()方法獲取// 這里用第二種方法,類名.classClass<?> classType = InvokeTester.class;// 生成新的對(duì)象:用newInstance()方法Object invokeTester = classType.newInstance();System.out.println(invokeTester instanceof InvokeTester); // 輸出true// 通過反射調(diào)用方法// 首先需要獲得與該方法對(duì)應(yīng)的Method對(duì)象Method addMethod = classType.getMethod("add", new Class[] { int.class,int.class });// 第一個(gè)參數(shù)是方法名,第二個(gè)參數(shù)是這個(gè)方法所需要的參數(shù)的Class對(duì)象的數(shù)組// 調(diào)用目標(biāo)方法Object result = addMethod.invoke(invokeTester, new Object[] { 1, 2 });System.out.println(result); // 此時(shí)result是Integer類型//調(diào)用第二個(gè)方法Method echoMethod = classType.getDeclaredMethod("echo", new Class[]{String.class});Object result2 = echoMethod.invoke(invokeTester, new Object[]{"Tom"});System.out.println(result2);} }

?

?

生成對(duì)象

?

  若想通過類的不帶參數(shù)的構(gòu)造方法來生成對(duì)象,我們有兩種方式:

  1.先獲得Class對(duì)象,然后通過該Class對(duì)象的newInstance()方法直接生成即可:

Class<?> classType = String.class;Object obj = classType.newInstance();

?

  2.先獲得Class對(duì)象,然后通過該對(duì)象獲得對(duì)應(yīng)的Constructor對(duì)象,再通過該Constructor對(duì)象的newInstance()方法生成

  (其中Customer是一個(gè)自定義的類,有一個(gè)無參數(shù)的構(gòu)造方法,也有帶參數(shù)的構(gòu)造方法):

Class<?> classType = Customer.class;// 獲得Constructor對(duì)象,此處獲取第一個(gè)無參數(shù)的構(gòu)造方法的Constructor cons = classType.getConstructor(new Class[] {});// 通過構(gòu)造方法來生成一個(gè)對(duì)象Object obj = cons.newInstance(new Object[] {});

?

  若想通過類的帶參數(shù)的構(gòu)造方法生成對(duì)象,只能使用下面這一種方式:

  (Customer為一個(gè)自定義的類,有無參數(shù)的構(gòu)造方法,也有一個(gè)帶參數(shù)的構(gòu)造方法,傳入字符串和整型)

Class<?> classType = Customer.class;Constructor cons2 = classType.getConstructor(new Class[] {String.class, int.class});Object obj2 = cons2.newInstance(new Object[] {"ZhangSan",20});

  可以看出調(diào)用構(gòu)造方法生成對(duì)象的方法和調(diào)用一般方法的類似,不同的是從Class對(duì)象獲取Constructor對(duì)象時(shí)不需要指定名字,而獲取Method對(duì)象時(shí)需要指定名字。

?

? ? ?原文轉(zhuǎn)至與http://www.cnblogs.com/mengdd/archive/2013/01/26/2877972.html

轉(zhuǎn)載于:https://www.cnblogs.com/onlysun/p/4530451.html

總結(jié)

以上是生活随笔為你收集整理的Java反射(Reflection)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。