java里什么是反射
本教程操作環(huán)境:windows7系統(tǒng)、java8版、DELL G3電腦。
什么是反射(Reflection )?
主要是指程序可以訪問、檢測和修改它本身狀態(tài)或行為的一種能力
Java反射?
在Java運行時環(huán)境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意一個對象,能否調(diào)用它的任意一個方法
Java反射機(jī)制主要提供了以下功能:
* 1.在運行時判斷任意一個對象所屬的類。
* 2.在運行時構(gòu)造任意一個類的對象。
* 3.在運行時判斷任意一個類所具有的成員變量和方法。
* 4.在運行時調(diào)用任意一個對象的方法。
Reflectio
Reflection是Java被視為動態(tài)(或準(zhǔn)動態(tài))語言的一個關(guān)鍵性質(zhì)。
這個機(jī)制允許程序在運行時透過Reflection APIs取得任何一個已知名稱的class的內(nèi)部信息。
包括其modifiers(諸如public、static等)、 superclass(例如Object)、實現(xiàn)了的 interfaces (例如Serializable)、也包括其fields和methods的所有信息,并可于運行時改變fields內(nèi)容或調(diào)用methods。
動態(tài)語言
動態(tài)語言的定義“程序運行時,允許改變程序結(jié)構(gòu)或者變量類型,這種語言稱為動態(tài)語言”。
從這個觀點看,Perl,Python,Ruby是動態(tài)語言,C++,Java,C#不是動態(tài)語言。
盡管在這樣的定義與分類下Java不是動態(tài)語言,它卻有著一個非常突出的動態(tài)相關(guān)機(jī)制:Reflection。這個字的意思是:反射、映像、倒影,用在Java身上指的是我們可以于運行時加載、探知、使用編譯期間完全未知的classes。
換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對象實體、或?qū)ζ鋐ields設(shè)值、或喚起其methods。
這種“看透”class的能力(the ability of the program to examine itself)被稱為introspection(內(nèi)省、內(nèi)觀、反?。?。Reflection和introspection是常被并提的兩個術(shù)語。
Java Reflection API簡介
在JDK中,主要由以下類來實現(xiàn)Java反射機(jī)制,這些類(除了第一個)都位于java.lang.reflect包中
Class類:代表一個類,位于java.lang包下。
Field類:代表類的成員變量(成員變量也稱為類的屬性)。
Method類:代表類的方法。
Constructor類:代表類的構(gòu)造方法。
Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法。
Class對象
要想使用反射,首先需要獲得待操作的類所對應(yīng)的Class對象。
Java中,無論生成某個類的多少個對象,這些對象都會對應(yīng)于同一個Class對象。
這個Class對象是由JVM生成的,通過它能夠獲悉整個類的結(jié)構(gòu)。
常用的獲取Class對象的3種方式:
1.使用Class類的靜態(tài)方法。例如:
Class.forName(“java.lang.String”);
登錄后復(fù)制
2.使用類的.class語法。如:
String.class;
登錄后復(fù)制
3.使用對象的getClass()方法。如:
String str = “aa”; Class
登錄后復(fù)制
例程1:獲取方法
例程DumpMethods類演示了Reflection API的基本作用,它讀取命令行參數(shù)指定的類名,然后打印這個類所具有的方法信息。
import java.lang.reflect.Method;
public class DumpMethods
{
public static void main(String[] args) throws Exception //在方法后加上這句,異常就消失了
{
//獲得字符串所標(biāo)識的類的class對象
Class<?> classType = Class.forName("java.lang.String");//在此處傳入字符串指定類名,所以參數(shù)獲取可以是一個運行期的行為,可以用args[0]
//返回class對象所對應(yīng)的類或接口中,所聲明的所有方法的數(shù)組(包括私有方法)
Method[] methods = classType.getDeclaredMethods();
//遍歷輸出所有方法聲明
for(Method method : methods)
{
System.out.println(method);
}
}
}
登錄后復(fù)制
例程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對象
// 前面用的方法是:Class.forName()方法獲取
// 這里用第二種方法,類名.class
Class<?> classType = InvokeTester.class;
// 生成新的對象:用newInstance()方法
Object invokeTester = classType.newInstance();
System.out.println(invokeTester instanceof InvokeTester); // 輸出true
// 通過反射調(diào)用方法
// 首先需要獲得與該方法對應(yīng)的Method對象
Method addMethod = classType.getMethod("add", new Class[] { int.class,
int.class });
// 第一個參數(shù)是方法名,第二個參數(shù)是這個方法所需要的參數(shù)的Class對象的數(shù)組
// 調(diào)用目標(biāo)方法
Object result = addMethod.invoke(invokeTester, new Object[] { 1, 2 });
System.out.println(result); // 此時result是Integer類型
//調(diào)用第二個方法
Method echoMethod = classType.getDeclaredMethod("echo", new Class[]{String.class});
Object result2 = echoMethod.invoke(invokeTester, new Object[]{"Tom"});
System.out.println(result2);
}
}
登錄后復(fù)制
生成對象
若想通過類的不帶參數(shù)的構(gòu)造方法來生成對象,我們有兩種方式:
1.先獲得Class對象,然后通過該Class對象的newInstance()方法直接生成即可:
Class<?> classType = String.class; Object obj = classType.newInstance();
登錄后復(fù)制
2.先獲得Class對象,然后通過該對象獲得對應(yīng)的Constructor對象,再通過該Constructor對象的newInstance()方法生成
(其中Customer是一個自定義的類,有一個無參數(shù)的構(gòu)造方法,也有帶參數(shù)的構(gòu)造方法):
Class<?> classType = Customer.class;
// 獲得Constructor對象,此處獲取第一個無參數(shù)的構(gòu)造方法的
Constructor cons = classType.getConstructor(new Class[] {});
// 通過構(gòu)造方法來生成一個對象
Object obj = cons.newInstance(new Object[] {});
登錄后復(fù)制
若想通過類的帶參數(shù)的構(gòu)造方法生成對象,只能使用下面這一種方式:
(Customer為一個自定義的類,有無參數(shù)的構(gòu)造方法,也有一個帶參數(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});
登錄后復(fù)制
可以看出調(diào)用構(gòu)造方法生成對象的方法和調(diào)用一般方法的類似,不同的是從Class對象獲取Constructor對象時不需要指定名字,而獲取Method對象時需要指定名字。
相關(guān)視頻教程推薦:Java視頻教程
以上就是java里什么是反射的詳細(xì)內(nèi)容,更多請關(guān)注風(fēng)君子博客其它相關(guān)文章!
總結(jié)
以上是生活随笔為你收集整理的java里什么是反射的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海贼王燃烧意志阵容
- 下一篇: 媒体查询常用屏幕分辨率参数