通過反射機制爲一個對象中的私有成員變量設置值及調用私有方法

通過反射機制爲一個對象中的私有成員變量設置值及調用私有方法 

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

總結:可以看到利用反射可以爲私有屬性的成員變量,調用私有屬性的函數,感覺有些不安全,但功能也十分強大,如果使用正確便能成爲利器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章