標籤:java反射機制
JAVA反射機制是在運行狀態中,對於任意一個類,都能夠得到這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法;這種動態擷取的資訊以及動態調用對象的方法的功能稱為java語言的反射機制.
概括一下:
反射就是讓你可以通過名稱來得到對象(類,屬性,方法)的技術。
例如我們可以通過類名來產生一個類的執行個體;
知道了方法名,就可以調用這個方法;知道了屬性名稱就可以訪問這個屬性的值。
1、擷取類對應的Class對象
運用(已知對象)getClass():Object類中的方法,每個類都擁有此方法。
如: String str = new String();
Class strClass = str.getClass();運用(已知子類的class) Class.getSuperclass():Class類中的方法,返回該Class的父類的Class;運用(已知類全名):Class.forName() 靜態方法運用(已知類): 類名.class
2、通過類名來構造一個類的執行個體
a、調用無參的建構函式:
Class newoneClass = Class.forName(類全名); newoneClass.newInstance();
b、調用有參的建構函式:我們可以自訂一個函數。
public Object newInstance(String className, Object[] args) throws Exception {
//args為參數數組
Class newoneClass = Class.forName(className); //得到參數的Class數組(每個參數的class組成的數組),由此來決定調用那個建構函式Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass();
}
Constructor cons = newoneClass.getConstructor(argsClass); //根據argsClass選擇函數return cons.newInstance(args); //根據具體參數執行個體化對象。
}
3、得到某個對象的屬性
a、非靜態屬性:首先得到class,然後得到這個class具有的field,然後以具體執行個體為參數調用這個field
public Object getProperty(Object owner, String fieldName) throws Exception { Class ownerClass = owner.getClass();//首先得到class Field field = ownerClass.getField(fieldName); //然後得到這個class具有的field,也可以通過getFields()得到所有的field Object property = field.get(owner); //owner指出了取得那個執行個體的這個屬性值,如果這個屬性是非公有的,這裡會報IllegalAccessException。
return property;
}
b、靜態屬性:
只有最後一步不同,由於靜態屬性屬於這個類,所以只要在這個類上調用這個field即可Object property = field.get(ownerClass);
4、執行某對象的方法
public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception { Class ownerClass = owner.getClass(); //也是從class開始的//得到參數的class數組,相當於得到參數列表的類型數組,來取決我們選擇哪個函數。
Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass();
}
//根據函數名和函數類型來選擇函數
Method method = ownerClass.getMethod(methodName, argsClass); return method.invoke(owner, args);//具體執行個體下,具體參數值下調用此函數
}
5、執行類的靜態方法
和上面的相似只是最後一行不需要指定具體執行個體
return method.invoke(null, args);
6、判斷是否為某個類的執行個體
public boolean isInstance(Object obj, Class cls) { return cls.isInstance(obj);
}
測試bean類:SimpleBean.java
Java代碼
package com.royzhou.bean;
public class SimpleBean {
private String name;
private String[] hobby;
public SimpleBean() {
}
public SimpleBean(String name, String[] hobby) { this.name = name; this.hobby = hobby;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
public String[] getHobby() {
return this.hobby;
}
public String toString() {
String returnValue = super.toString() + "\n"; returnValue += "name:=" + this.name + "\n"; if(this.hobby != null) {
returnValue += "hobby:";
for(String s : this.hobby) { returnValue += s + ",";
}
returnValue += "\n";
}
return returnValue;
}
}
package com.royzhou.bean;
public class SimpleBean {
private String name;
private String[] hobby;
public SimpleBean() {
}
public SimpleBean(String name, String[] hobby) { this.name = name; this.hobby = hobby;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
public String[] getHobby() {
return this.hobby;
}
public String toString() {
String returnValue = super.toString() + "\n"; returnValue += "name:=" + this.name + "\n"; if(this.hobby != null) {
returnValue += "hobby:";
for(String s : this.hobby) { returnValue += s + ",";
}
returnValue += "\n";
}
return returnValue;
}
}
反射測試類別:ReflectTest.java
Java代碼
package com.royzhou.bean;
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws Exception {
Class clazz = SimpleBean.class;
//使用無參建構函式執行個體化bean
SimpleBean sb = (SimpleBean)clazz.newInstance(); System.out.println(sb);
//使用有參建構函式執行個體化bean
Constructor constructor = clazz.getConstructor(new Class[]{String.class, String[].class}); sb = (SimpleBean)constructor.newInstance(new Object[]{"royzhou",new String[]{"football","basketball"}}); System.out.println(sb);
//為name欄位設定值
Field field = clazz.getDeclaredField("name"); field.setAccessible(true); //避免private不可訪問拋出異常field.set(sb, "royzhou1985"); System.out.println("modify name using Field:=" + sb.getName() + "\n");
//列出類SimpleBean的所有方法
Method[] methods = clazz.getDeclaredMethods(); System.out.println("get methods of class SimpleBean:");
for(Method method : methods) {
if("setHobby".equals(method.getName())) {
//動態調用類的方法來為hobby設定值
method.invoke(sb, new Object[]{new String[]{"tennis","fishing"}});
}
System.out.println(method.getName());
}
System.out.println("\nset by invoke Method"); System.out.println(sb);
}
}
package com.royzhou.bean;
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws Exception {
Class clazz = SimpleBean.class;
//使用無參建構函式執行個體化bean
SimpleBean sb = (SimpleBean)clazz.newInstance(); System.out.println(sb);
//使用有參建構函式執行個體化bean
Constructor constructor = clazz.getConstructor(new Class[]{String.class, String[].class}); sb = (SimpleBean)constructor.newInstance(new Object[]{"royzhou",new String[]{"football","basketball"}}); System.out.println(sb);
//為name欄位設定值
Field field = clazz.getDeclaredField("name"); field.setAccessible(true); //避免private不可訪問拋出異常field.set(sb, "royzhou1985"); System.out.println("modify name using Field:=" + sb.getName() + "\n");
//列出類SimpleBean的所有方法
Method[] methods = clazz.getDeclaredMethods(); System.out.println("get methods of class SimpleBean:");
for(Method method : methods) {
if("setHobby".equals(method.getName())) {
//動態調用類的方法來為hobby設定值
method.invoke(sb, new Object[]{new String[]{"tennis","fishing"}});
}
System.out.println(method.getName());
}
System.out.println("\nset by invoke Method"); System.out.println(sb);
}
}
輸出結果:
[email protected]
name:=null
[email protected]
name:=royzhou
hobby:football,basketball,
modify name using Field:=royzhou1985
get methods of class SimpleBean:
setHobby
getHobby
getName
toString
setName
set by invoke Method
[email protected]
name:=royzhou1985
hobby:tennis,fishing,
...
JAVA反射機制(一)