個人博客:haichenyi.com。感謝關(guān)注
簡介
??在運(yùn)行過程中,對任意一個類,都能知道這個類的所有屬性和方法。對于任一個對象,都能調(diào)用他的任意一個方法和屬性。這種動態(tài)獲取信息以及動態(tài)調(diào)用對象的方法稱為java語言的反射機(jī)制
用法
我這里就列出我常用的兩個方法私有類和變量
方法Methods
| 方法 | 用途 |
|---|---|
| getDeclaredMethods() | 獲取當(dāng)前類的所有方法,包括public/private/protected/default修飾的方法 |
| getDeclaredMethod(String name, Class<?>... parameterTypes) | 獲取當(dāng)前類的某一個方法,包括public/private/protected/default修飾的方法 |
| getMethods() | 獲取當(dāng)前類和所繼承父類的public標(biāo)識的所有方法,僅僅包括public |
| getMethod(String name, Class<?>... parameterTypes) | 獲取當(dāng)前類和所繼承父類的public標(biāo)識的某一個方法,僅僅包括public |
??上面就是兩個類型的方法,一個是只獲取當(dāng)前類的方法,獲取當(dāng)前類的方法,包括所有類型的方法:public/private/protected/default。還有一個是獲取當(dāng)前類和所繼承的父類的方法,僅僅包括public修飾的方法。
調(diào)用方式
//在TakePhotoActivity.class類中有兩個重載方法,一個無參,一個有一個String類型的參數(shù)
private void myTest(){
Log.v("WZ","myTest無參");
}
private void myTest(String msg){
Log.v("WZ","myTest有參");
}
調(diào)用無參的方法
TakePhotoActivity takePhotoActivity = new TakePhotoActivity();//new 一個類對象
try {
Class<? extends TakePhotoActivity> aClass1 = takePhotoActivity.getClass();//通過getClass方法獲取類對象
//Class<?> aClass = Class.forName("com.haichenyi.mytakephoto.TakePhotoActivity");//通過路徑獲取Class對象
Method myTest = aClass1.getDeclaredMethod("myTest");
myTest.setAccessible(true);//參數(shù)值為true,禁止訪問控制檢查
myTest.invoke(takePhotoActivity);//執(zhí)行私有方法
} catch (Exception e) {
e.printStackTrace();
Log.v("WZ", e.getMessage());
}
調(diào)用有參的方法
TakePhotoActivity takePhotoActivity = new TakePhotoActivity();//new 一個類對象
Class[] arr = new Class[]{String.class};
try {
Class<? extends TakePhotoActivity> aClass1 = takePhotoActivity.getClass();//通過getClass方法獲取類對象
//Class<?> aClass = Class.forName("com.haichenyi.mytakephoto.TakePhotoActivity");//通過路徑獲取Class對象
Method myTest = aClass1.getDeclaredMethod("myTest",arr);
myTest.setAccessible(true);//參數(shù)值為true,禁止訪問控制檢查
myTest.invoke(takePhotoActivity,"s");//執(zhí)行私有方法
} catch (Exception e) {
e.printStackTrace();
Log.v("WZ", e.getMessage());
}
有參的方法,在獲取方法的時候,傳一個Class[]數(shù)組,里面的值就是參數(shù)類型的類?;蛘哌€有另一種傳的方法,前面獲取方法的時候:
- 獲取方法的時候,無參的傳一個空的Class[],有參就傳有值的Class[]數(shù)組
- 執(zhí)行方法的時候,無參的傳一個空的Object[],有參就傳有值的Object[]數(shù)組,至于傳的值隨便寫,類型一樣就行
變量Field
| 方法 | 用途 |
|---|---|
| getDeclaredFields() | 獲取當(dāng)前類的所有類型的全局變量,包括public/private/protected/default修飾的變量 |
| getDeclaredField(String name) | 獲取當(dāng)前類的某一個類型的全局變量,包括public/private/protected/default修飾的變量 |
| getFields() | 獲取當(dāng)前類和繼承父類的所有用public修飾的變量 |
| getField(String name) | 獲取當(dāng)前類和繼承父類的某一個用public修飾的變量 |
調(diào)用方式
//在TakePhotoActivity里面定義
private int flag;
獲取變量
TakePhotoActivity takePhotoActivity = new TakePhotoActivity();//new 一個類對象
try {
Class<? extends TakePhotoActivity> aClass1 = takePhotoActivity.getClass();//通過getClass方法獲取類對象
//Class<?> aClass = Class.forName("com.haichenyi.mytakephoto.TakePhotoActivity");//通過路徑獲取Class對象
Field flag = aClass.getDeclaredField("flag");
flag.setAccessible(true);
Object o = flag.get(takePhotoActivity);//這里就獲取到了對象
...//做你自己的邏輯處理
} catch (Exception e) {
e.printStackTrace();
Log.v("WZ", e.getMessage());
}
設(shè)置變量的值
//獲取變量的值跟上面一樣
flag.set(takePhotoActivity,10);//這樣寫會改變TakePhotoActivity中flag的值
工具類
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Author: 海晨憶.
* Date: 2018/3/6
* Desc: 反射工具類
*/
public class ReflectionUtil {
/***
* 獲取私有成員變量的值
*
*/
public static Object getValue(Object instance, String fieldName)
throws IllegalAccessException, NoSuchFieldException {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true); // 參數(shù)值為true,禁止訪問控制檢查
return field.get(instance);
}
/***
* 設(shè)置私有成員變量的值
*
*/
public static void setValue(Object instance, String fileName, Object value)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field field = instance.getClass().getDeclaredField(fileName);
field.setAccessible(true);
field.set(instance, value);
}
/***
* 訪問私有方法
*
*/
public static Object callMethod(Object instance, String methodName, Class[] classes, Object[] objects)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Method method = instance.getClass().getDeclaredMethod(methodName, classes);
method.setAccessible(true);
return method.invoke(instance, objects);
}
}