在java中,反射主要是指程式可以存取、偵測和修改它本身狀態或行為的一種能力。 Java反射機制的主要功能:1、在執行時期判斷任意一個物件所屬的類別;2、在執行時建構任意一個類別的物件;3、在執行時期呼叫任意一個物件的方法等。
本教學操作環境:windows7系統、java8版、DELL G3電腦。
主要是指程式可以存取、偵測和修改它本身狀態或行為的一種能力
在Java執行環境中,對於任意一個類,能否知道這個類別有哪些屬性和方法?對於任意一個對象,能否呼叫它的任意一個方法
Java反射機制主要提供了以下功能:
* 1.在執行時判斷任意一個物件所屬的類別。
* 2.在運行時建構任一個類別的物件。
* 3.在執行時判斷任一個類別所具有的成員變數和方法。
* 4.在執行時呼叫任一個物件的方法。
Reflection是Java被視為動態(或準動態)語言的關鍵性質。
這個機制允許程式在運行時透過Reflection APIs取得任何一個已知名稱的class的內部資訊。
包括其modifiers(諸如public、static等)、 superclass(例如Object)、實現了的interfaces (例如Serializable)、也包括其fields和methods的所有信息,並可於運行時改變fields內容或調用methods。
動態語言的定義「程式執行時,允許改變程式結構或變數類型,這種語言稱為動態語言」。
從這個觀點看,Perl,Python,Ruby是動態語言,C ,Java,C#不是動態語言。
儘管在這樣的定義與分類下Java不是動態語言,它卻有著非常突出的動態相關機制:Reflection。這個字的意思是:反射、映像、倒影,用在Java身上指的是我們可以於執行時間載入、探知、使用編譯期間完全未知的classes。
換句話說,Java程式可以載入一個執行時才得知名稱的class,得知其完整建構(但不包括methods定義),並產生其物件實體、或對其fields設值、或喚起其methods。
這種「看透」class的能力(the ability of the program to examine itself)稱為introspection(內省、內觀、反省)。 Reflection和introspection是常被並提的兩個術語。
在JDK中,主要由以下類別來實作Java反射機制,這些類別(除了第一個)都位於java.lang. reflect套件中
Class類:代表一個類,位於java.lang套件下。
Field類別:代表類別的成員變數(成員變數也稱為類別的屬性)。
Method類別:代表類別的方法。
Constructor類別:代表類別的建構方法。
Array類別:提供了動態建立數組,以及存取陣列的元素的靜態方法。
要想使用反射,首先需要取得待操作的類別所對應的Class物件。
Java中,無論產生某個類別的多少個對象,這些物件都會對應到同一個Class物件。
這個Class物件是由JVM產生的,透過它能夠獲悉整個類別的結構。
常用的取得Class物件的3種方式:
1.使用Class類別的靜態方法。例如:
Class.forName(“java.lang.String”);
2.使用類別的.class語法。如:
String.class;
3.使用物件的getClass()方法。如:
String str = “aa”; Class
例程1:取得方法
例程DumpMethods類別示範了Reflection API的基本作用,它讀取命令列參數指定的類別名,然後列印這個類別所具有的方法資訊。
import java.lang.reflect.Method; public class DumpMethods { public static void main(String[] args) throws Exception //在方法后加上这句,异常就消失了 { //获得字符串所标识的类的class对象 Class<?> classType = Class.forName("java.lang.String");//在此处传入字符串指定类名,所以参数获取可以是一个运行期的行为,可以用args[0] //返回class对象所对应的类或接口中,所声明的所有方法的数组(包括私有方法) Method[] methods = classType.getDeclaredMethods(); //遍历输出所有方法声明 for(Method method : methods) { System.out.println(method); } } }
例程2:透過反射呼叫方法
透過反射呼叫方法。詳情請見程式碼及註解:
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 { // 以前的常规执行手段 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 // 通过反射调用方法 // 首先需要获得与该方法对应的Method对象 Method addMethod = classType.getMethod("add", new Class[] { int.class, int.class }); // 第一个参数是方法名,第二个参数是这个方法所需要的参数的Class对象的数组 // 调用目标方法 Object result = addMethod.invoke(invokeTester, new Object[] { 1, 2 }); System.out.println(result); // 此时result是Integer类型 //调用第二个方法 Method echoMethod = classType.getDeclaredMethod("echo", new Class[]{String.class}); Object result2 = echoMethod.invoke(invokeTester, new Object[]{"Tom"}); System.out.println(result2); } }
若想透過類別的不帶參數的建構方法來產生對象,我們有兩種方式:
1.先取得Class對象,再透過該Class物件的newInstance()方法直接產生即可:
Class<?> classType = String.class; Object obj = classType.newInstance();
2.先取得Class對象,再透過該物件取得對應的Constructor對象,再透過該Constructor物件的newInstance()方法產生
(其中Customer是一個自訂的類,有一個無參數的建構方法,也有參數的建構方法):
Class<?> classType = Customer.class; // 获得Constructor对象,此处获取第一个无参数的构造方法的 Constructor cons = classType.getConstructor(new Class[] {}); // 通过构造方法来生成一个对象 Object obj = cons.newInstance(new Object[] {});
若想透過類別的帶參數的構造方法產生對象,只能使用下面這一種方式:
(Customer為一個自訂的類,有無參數的構造方法,也有一個帶參數的構造方法,傳入字串和整數)
Class<?> classType = Customer.class; Constructor cons2 = classType.getConstructor(new Class[] {String.class, int.class}); Object obj2 = cons2.newInstance(new Object[] {"ZhangSan",20});
可以看出调用构造方法生成对象的方法和调用一般方法的类似,不同的是从Class对象获取Constructor对象时不需要指定名字,而获取Method对象时需要指定名字。
相关视频教程推荐:Java视频教程
以上是java裡什麼是反射的詳細內容。更多資訊請關注PHP中文網其他相關文章!