反射必會方法
繼上篇,總結整理:
- 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);
(5、6)
//獲取調用者
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表示可以操作