一 從一個執行個體出發--在運行時擷取某個對象相關資訊
1. 我們首先定義一個Customer類,表示客戶的相關資訊
public class Customer {private Long id;private String name;private int age;private String phone;public Customer() {}public Customer(Long id,String name,int age,String phone) {this.id=id;this.name=name;this.age=age;this.phone=phone;}public final Long getId() {return id;}public void setId(Long id) {this.id=id;}public final String getName() {return name;}public final void setName(String name) {this.name=name;}public final int getAge() {return age;}public void setAge(int age) {this.age=age;}public final String getPhone() {return phone;}public void setAge(String phone) {this.phone=phone;}}
2. 現在我們寫一個類,實現擷取Customer執行個體所有的構造方法和普通方法及屬性資訊
import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectionApplication {/** * @param args */public static void ShowObjectInfo(Object obj) throws Exception {Class c=obj.getClass();int i;System.out.println(obj.toString()+"所有的構造方法是:");Constructor [] cs=c.getConstructors();for(i=0;i<cs.length;i++) {System.out.println(cs[i].toString());}System.out.println(obj.toString()+"所有的聲明的方法是:");Method [] methods=c.getDeclaredMethods();for(i=0;i<methods.length;i++) {System.out.println(methods[i].toString());}System.out.println(obj.toString()+"所有的聲明的屬性是:");Field[] fields=c.getDeclaredFields();for(i=0;i<fields.length;i++) {System.out.println(fields[i].toString());}}public static void main(String[] args) throws Exception {// TODO Auto-generated method stubCustomer customer=new Customer(001L,"wangzhicheng",28,"13866916216");ShowObjectInfo(customer);}}
3. 運行結果是:
Customer@1fb8ee3所有的構造方法是:public Customer()public Customer(java.lang.Long,java.lang.String,int,java.lang.String)Customer@1fb8ee3所有的聲明的方法是:public void Customer.setId(java.lang.Long)public final int Customer.getAge()public void Customer.setAge(int)public void Customer.setAge(java.lang.String)public final java.lang.String Customer.getPhone()public final java.lang.String Customer.getName()public final java.lang.Long Customer.getId()public final void Customer.setName(java.lang.String)Customer@1fb8ee3所有的聲明的屬性是:private java.lang.Long Customer.idprivate java.lang.String Customer.nameprivate int Customer.ageprivate java.lang.String Customer.phoneprivate java.lang.String Customer.phone
二 什麼是反射
從以上執行個體中可以看出,在Java運行環境中,對於任意一個類或對象,我們可以知道這個類或對象有哪些屬性和方法。不僅如此,對於任意一個對象,我們可以在運行時,調用它的任意方法。這種動態擷取類的資訊及調用對象的方法就是Java的反射技術。
三 為什麼會有反射的存在--從java.lang.Class類說起
Java程式在運行時,Java運行時系統一直對所有的對象進行所謂的運行時類型標識,這個工作記錄著每個對象所屬的類,用來儲存這些類型的資訊是Class類。所以我們可以通過Class擷取類的相關資訊,正如上例所示。
四 反射技術的簡單應用--運行時複製對象
import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Member;import java.lang.reflect.Method;public class CopyObject {/** * @param args */public static Object copy(Object source) throws Exception {Class<?>c=source.getClass(); //擷取source類型對象Object obj=c.newInstance(); //擷取source執行個體對象Field[] fields=c.getDeclaredFields(); //擷取聲明的屬性for(int i=0;i<fields.length;i++) {Field field=fields[i];String fieldName=field.getName(); //擷取每個屬性String firstLetter=fieldName.substring(0,1).toUpperCase(); //將屬性名稱首字母轉化為大寫String getMethodName="get"+firstLetter+fieldName.substring(1); //擷取get方法名稱String setMethodName="set"+firstLetter+fieldName.substring(1); //擷取set方法名稱Method getMethod=c.getMethod(getMethodName, new Class[]{}); //擷取get方法Method setMethod=c.getMethod(setMethodName, new Class[]{field.getType()});//擷取set方法,此方法的類型是field.getTypeObject value=getMethod.invoke(source, new Object[]{});//調用get方法System.out.println(fieldName+":"+value);setMethod.invoke(obj, new Object[]{value});//調用set方法}return obj;}public static void main(String[] args) throws Exception {// TODO Auto-generated method stubCustomer customer=new Customer(001L,"wangzhicheng",28,"13866916216");Customer customercopy=(Customer)copy(customer);System.out.println("拷貝的對象是:");System.out.println(customercopy.getId()+" "+customercopy.getName()+" "+customercopy.getAge()+" "+customercopy.getPhone());}}
運行結果:
id:1name:wangzhichengage:28phone:13866916216拷貝的對象是:1 wangzhicheng 28 13866916216
五 反射也有副作用,影響程式的效能
六 更多參考資料:Java Reflection in Action