通過反射機制爲一個對象中的私有成員變量設置值及調用私有方法
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
public class Test {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException, InstantiationException {
System.out.println("使用反射機制爲成員變量賦值:");
Person person = new Person();
Tools.setProperty(person, "name", "小明");
Tools.setProperty(person, "age", 18);
System.out.println(person.toString());
Tools.setProperty(person, "name", "我纔不是小明,我是小紅");
System.out.println(person.toString());
System.out.println("\n獲得成員變量的各種信息:");
Tools.getField(person);
System.out.println("\n獲得成員函數的各種信息:");
Tools.getMethod(person);
System.out.println("\n通過反射機制調用各種方法:");
Tools.invokeMethod(person);
}
}
class Tools {
//通過反射機制調用各種成員方法
public static void invokeMethod(Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException {
Class clazz=Class.forName(object.getClass().getName());//動態加載類,獲取當前類的Class對象
//獲取Person類名稱爲getName方法
Method method1 = clazz.getDeclaredMethod("getName");
// 取消訪問檢查
method1.setAccessible(true);
//調用成員方法
System.out.println(method1.invoke(object));
//獲取Person類名稱爲setName帶一個參數方法
Method method2 = clazz.getDeclaredMethod("setName", String.class);
// 取消訪問檢查
method2.setAccessible(true);
//調用成員方法
method2.invoke(object, "我改名字了");
System.out.println(method1.invoke(object));
//獲取Person類名稱爲setName帶多個參數方法
Method method3 = clazz.getDeclaredMethod("setNameAge", String.class, int.class);
// 取消訪問檢查
method3.setAccessible(true);
//調用成員方法
method3.invoke(object, "我又改名字了", 3);
System.out.println(method1.invoke(object));
}
//使用反射機制爲成員變量賦值:
public static void setProperty(Object obj, String propertyName, Object value)
throws NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException {
// 反射獲取字節碼文件對象
Class c = obj.getClass();
// 獲取該對象的propertyName成員變量
Field field = c.getDeclaredField(propertyName); //通過參數來獲取
// 取消訪問檢查
field.setAccessible(true);
// 給對象的成員變量賦值爲指定的值--->value
field.set(obj, value);
}
//使用反射機制獲得成員變量的各種信息:
public static void getField(Object object) throws IllegalArgumentException, IllegalAccessException {
//獲得類
Class clazz = object.getClass();
// 獲取實體類的所有屬性信息,返回Field數組
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
int mod = field.getModifiers();
// 取消訪問檢查
field.setAccessible(true);
System.out.println(
((mod == 0) ? "" : (Modifier.toString(mod)))
+ "······" + field.getType().getSimpleName()
+ "······" + field.getName()
+ "······" + field.get(object)
);
}
}
//使用反射機制獲得成員函數的各種信息:
public static void getMethod(Object object) {
//獲得類
Class clazz = object.getClass();
// 獲取實體類的所有方法信息,返回Method數組
Method[] methods = clazz.getMethods();
for (Method method : methods) {
int mod = method.getModifiers();
System.out.println(
((mod == 0) ? "" : (Modifier.toString(mod)))
+ "······" + method.getReturnType().getSimpleName()
+ "······" + method.getName()
+ "······" + Tools.getMethodParameter(method)
);
}
}
public static String getMethodParameter(Method method) {
Parameter[] parameters = method.getParameters();
String str = "(";
for (Parameter parameter : parameters) {
str += parameter.getType().getSimpleName();
str += " ";
str += parameter.getName();
str += ", ";
}
if(str.length()>2) {
str = str.substring(0, str.length()-2);
}
str += ")";
return str;
}
}
class Person {
private String name; // 注意此處name是私有的,外界是無法訪問的。
public int age;
private String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void setNameAge(String name, int no) {
this.name = "名字:" + name + ",在家排行:" + no;
}
@Override
public String toString() {
return name + "······" + age;
}
}
運行結果:
使用反射機制爲成員變量賦值:
小明······18
我纔不是小明,我是小紅······18獲得成員變量的各種信息:
private······String······name······我纔不是小明,我是小紅
public······int······age······18獲得成員函數的各種信息:
public······String······toString······()
public······void······setName······(String arg0)
public······void······setAge······(int arg0)
public······int······getAge······()
public final······void······wait······()
public final······void······wait······(long arg0, int arg1)
public final native······void······wait······(long arg0)
public······boolean······equals······(Object arg0)
public native······int······hashCode······()
public final native······Class······getClass······()
public final native······void······notify······()
public final native······void······notifyAll······()通過反射機制調用各種方法:
我纔不是小明,我是小紅
我改名字了
名字:我又改名字了,在家排行:3
總結:可以看到利用反射可以爲私有屬性的成員變量,調用私有屬性的函數,感覺有些不安全,但功能也十分強大,如果使用正確便能成爲利器。