Java中的反射(二)

反射必會方法

繼上篇,總結整理:

  • Method成員方法涉及到的方法
  • Field成員變量涉及到的方法
  • 給予暴力反射私有化內容的權限操作

1.Method成員方法涉及到的方法

通過Class對象來獲取Method對象,需要考慮的內容有:

  • 參數
  • 方法名
  • 權限修飾符

方法

(1)Method[] getMethods();
	獲取類內所有public成員方法,包括繼承而來的public方法。
(2)Method[] getDeclaredMethods();
【暴力反射】
	獲取類內所有成員方法,包括private方法,但不包括繼承而來的方法
(3)Method getMethod(String methodName, Class... parameterTypes);
	根據指定的【方法名】和對應的【參數類型】,獲取對應的public成員方法
	【其中參數】:
		methodName:
			方法名,指定獲取的是哪一個方法
		parameterTypes:
			Class:用於約束當前使用的參數數據類型
			... :不定長參數,方法參數的【個數】、【順序】、【有參無參】問題
		如:
			cls是Class類對象
			cls.getMethod("setName", String.class);
			cls.getMethod("getName");
(4)Method getDeclaredMethod(String methodName, Class... parameterTypes);
【暴力反射】
	根據指定的【方法名】和對應的【參數類型】,獲取對應的成員方法,包括【private】成員方
	法,【但不包括】繼承來的方法。
	【其中參數】:
		methodName:
			方法名,指定獲取的是哪一個方法
		parameterTypes:
			Class:用於約束當前使用的參數數據類型
			... :不定長參數,方法參數個數、順序、有參無參問題
		如:
			cls是Class類對象
			cls.getMethod("setName", String.class);
			cls.getMethod("getName");
(5)Object invoke(Object obj, Object... arguments);
	通過Method類對象調用,執行對應的方法
	【其中參數】:
		obj:
			當前方法的執行者
		arguments:
			Object...:不定長參數,執行當前方法所需的實際參數

以上方法的代碼演示

//需要的包
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//方法需拋出的異常較多
public static void main(String[] args) throws ClassNotFoundException,
			NoSuchMethodException, SecurityException, InstantiationException,
			IllegalAccessException, IllegalArgumentException, InvocationTargetException

//獲取Class類對象cls,用於方法使用
//根據指定的包名.類名,獲取對應的Class對象
Class<?> cls = Class.forName("com.reflect.Person");

(1)獲取類內所有【public成員方法】,包括繼承而來的方法
Method[] methods = cls.getMethods();
for(Method method : methods){
	System.out.println(method);
}

(2)獲取類內所有【成員方法】,包括【private】成員方法,【但是不包括】父類繼承而來的方法
【暴力反射】
Method[] declaredMethods = cls.getDeclaredMethods();
for (Method method : declaredMethods) {
	System.out.println(method);
}

(3)根據指定的【方法名】和【參數類型】,獲取類內【public】成員方法
Method game1 = cls.getMethod("game");
Method game2 = cls.getMethod("game", String.class);
System.out.println(game1);
System.out.println(game2);

(4)根據指定的【方法名】和【參數類型】,獲取類內【private】成員方法
【暴力反射】
Method declaredMethod1 = cls.getDeclaredMethod("testPrivate");
Method declaredMethod2 = cls.getDeclaredMethod("testPrivate",String.class);
System.out.println(declaredMethod1);
System.out.println(declaredMethod2);

(5)給予暴力反射操作權限的情況下,執行私有化成員方法
Object obj = cls.getConstructor().newInstance();
//執行【public】成員方法
game1.invoke(obj);
game2.invoke(obj, "WOT");

//給予暴力反射操作權限的情況下,執行私有化成員方法
declaredMethod1.setAccessible(true);
declaredMethod1.invoke(obj);	
declaredMethod2.setAccessible(true);
declaredMethod2.invoke(obj, "烤羊排");

2.Field成員變量涉及到的方法

方法

(1)Field[] getFields();
	獲取類內所有【public】成員變量
(2)Field[] getFields();
【暴力反射】
	獲取類內所有成員變量,包括【private】成員成員變量
(3)Field getField(String fieldName);
	獲取【指定】變量名的成員變量對象,要求是【public】成員變量
(4)Field getDeclaredField(String fieldName);
【暴力反射】
	獲取指定變量名的成員變量對象,包括private私有化修飾的成員變量
(5)void set(Object obj, Object value);
	設置指定調用者中對應成員變量的數據
		obj : 調用者
		value: 對應當前成員變量需要賦值的內容
(6)Object get(Object obj);
	獲取指定調用者中指定成員變量的數據
		obj: 調用者

以上方法的代碼演示

//導包
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
//拋出異常
public static void main(String[] args) 
			throws ClassNotFoundException, NoSuchFieldException,
			 SecurityException, InstantiationException, IllegalAccessException, 
			IllegalArgumentException, InvocationTargetException, NoSuchMethodException { }
//根據指定的包名.類名,獲取對應的Class對象,便於以下方法使用
Class<?> cls = Class.forName("com.qfedu.a_reflect.Person");

(1)獲取類內所有public修飾的成員變量
Field[] fields = cls.getFields();
for (Field field : fields) {
	System.out.println(field);
}

(2)獲取類內所有成員變量,包括【private】成員成員變量
Field[] declaredFields = cls.getDeclaredFields();	
for (Field field : declaredFields) {
	System.out.println(field);
}

(3)	獲取【指定】變量名的成員變量對象,要求是【public】成員變量
Field field = cls.getField("test");
System.out.println(field);

(4)獲取指定變量名的成員變量對象,包括private私有化修飾的成員變量
Field id = cls.getDeclaredField("id");
Field name = cls.getDeclaredField("name");
System.out.println(id);
System.out.println(name);

(56)
//獲取調用者
Object obj = cls.getConstructor().newInstance();
System.out.println(obj);
(5)設置指定調用者中對應成員變量的數據
field.set(obj, 20);
System.out.println(obj);
		
id.setAccessible(true);
name.setAccessible(true);
		
id.set(obj, 1);
name.set(obj, "騷磊");
		
System.out.println(obj);

(6)獲取指定調用者中指定成員變量的數據
System.out.println(field.get(obj));
System.out.println(id.get(obj));
System.out.println(name.get(obj));

3.給予暴力反射私有化內容的權限操作

setAccessible(boolean flag);
	給予Constructor,Method, Field對象,私有化內容,操作權限設置
	true表示可以操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章