java反射淺析

在Java運行時環境中,對於任意一個類,能否知道這個類有哪些屬性和方法?對於任意一個對象,能否調用它的任意一個方法?答案是肯定的。這種動態獲取類的信息以及動態調用對象的方法的功能來自於Java 語言的反射(Reflection)機制。

[color=red]Java 反射機制主要提供了以下功能:

在運行時判斷任意一個對象所屬的類。
在運行時構造任意一個類的對象。
在運行時判斷任意一個類所具有的成員變量和方法。
在運行時調用任意一個對象的方法[/color]

Reflection 是Java被視爲動態(或準動態)語言的一個關鍵性質。這個機制允許程序在運行時透過Reflection API取得任何一個已知名稱的class的內部信息,包括其modifiers(諸如public, static 等等)、superclass(例如Object)、實現之interfaces(例如Serializable),也包括fields和methods的所有信息,並可於運行時改變fields內容或調用methods

[color=red]在JDK中,主要由以下類來實現Java反射機制,這些類都位於java.lang.reflect包中
Class類:代表一個類。
Field 類:代表類的成員變量(成員變量也稱爲類的屬性)。
Method類:代表類的方法。
Constructor 類:代表類的構造方法。
Array類:提供了動態創建數組,以及訪問數組的元素的靜態方法[/color]

先看一個簡單的例子



package com.smallq.reflection;

import java.lang.reflect.Method;

/**
* 最簡反射示例
*
* @author smallq
*
*/
public class ShowMethods {

/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 根據完整的類名得到對象的類型
Class<?> classType = Class.forName("java.util.Date");
// 取對象的所有方法
Method method[] = classType.getDeclaredMethods();
// 輸出
for (int i = 0; i < method.length; i++) {
System.out.println(method[i].toString());
}
}

}




上面的例子是給定一個完整的類名。然後就可以知道所有這個類中的公共方法
那麼怎麼調用類中的方法呢。看下面的例子


package com.smallq.reflection;
import java.lang.reflect.Method;

/**
* 反射例子
*
* @author smallq
*
*/
public class InvokeTester {
public int add(int a, int b) {
return a + b;
}

public String echo(String str) {
return "echo: " + str;
}

public static void main(String[] args) throws Exception, Exception {

// 得到對象類型
Class<?> classType = InvokeTester.class;
// 根據類型實例化對象,這裏使用newInstance方法只能實例化具有無參構造方法的對象
Object invokeTester = classType.newInstance();
/**
* 如果類提供了有參構造方法.則使用下面的方法得到實例,有參則在下面兩個大括號中寫 new Class.和new Object是對應的
*/

// Object invokeTester = classType.getConstructor(new
// Class[]{}).newInstance(new Object[]{});
// 取對象的方法(方法名,方法參數的類型)
Method addMethod = classType.getMethod("add", new Class[] { int.class,
int.class });
// 調用InvokeTester對象的add()方法
// 提供參數(對象的實例,方法需要的參數)方法參數必須是類類型.不能是基本類型.但是jdk1.5提供了自動裝箱.所以int也可以
Object result = addMethod.invoke(invokeTester, new Object[] {
new Integer(100), 400 });
System.out.println(result.toString());

/**
* 同理
*/
Method echoMethod = classType.getMethod("echo",
new Class[] { String.class });
Object object = echoMethod.invoke(invokeTester, "Hello");
System.out.println(object.toString());
}
}


jkd提供了invoke方法調用對象的方法

[color=red]在java.lang.Object 類中定義了getClass()方法,因此對於任意一個Java對象,都可以通過此方法獲得對象的類型。Class類是Reflection API 中的核心類,它有以下方法
getName():獲得類的完整名字。
getFields():獲得類的public類型的屬性。
getDeclaredFields():獲得類的所有屬性。
getMethods():獲得類的public類型的方法。
getDeclaredMethods():獲得類的所有方法[/color]

如果想反射一個類。那麼必須知道他的類類型。也就是class object
一共有如下幾種方法


1)getClass() //String str="aaa";
//Class c=str.getClass();
2)靜態方法
Class.forName(); //Class c=Class.forName("java.lang.String");

3).class語法 //Class c=String.class

4)原聲數據類型的type語法 //Boolean.TYPE

5)getSupperclass //String str="aaa";
//Class c=str.getSuperclass(); 得到的是object類的類型

發佈了21 篇原創文章 · 獲贊 1 · 訪問量 3572
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章