Android反射的使用

发布时间 2023-05-28 18:52:07作者: 呢哇哦比较
public class MyReflectUtils {
private MyReflectUtils(int i){}

public MyReflectUtils(){}
/**
* 三种方式获取Class对象
* Class对象是一个单例
* @param obj
* @param classFullName
*/
public static void getMyClass(Object obj,String classFullName){
//1.通过类引用获取
Class<MyReflectUtils> aClass = MyReflectUtils.class;
//2.通过对象的方法获取
Class<?> oClass = obj.getClass();
//3.通过类的全路径获取
try {
Class<?> nClass = Class.forName(classFullName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

/**
* 获取类实例,两种方法
*/
public static void getMyInstance(){
Class<?> aClass = MyReflectUtils.class;
//1.只能是包含无参构造且构造是public类型的类
//过时了,由clazz.getDeclaredConstructor().newInstance()替代
try {
final Object aInstance = aClass.newInstance();
System.out.println(aInstance);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}

//2.通过获取类声明的构造函数
//2.1
final Constructor<?>[] dConstructors = aClass.getDeclaredConstructors();
for (Constructor<?> item : dConstructors) {
//返回包含了不管用什么权限修饰符修饰的所有构造方法
}
//2.2
try {
final Constructor<?> dConstructor = aClass.getDeclaredConstructor(int.class);//通过形参类型获取相应的构造
// final Constructor<?> constructor = aClass.getConstructor();//获取仅由public修饰的构造
if (!dConstructor.isAccessible()){
dConstructor.setAccessible(true);//注意:构造可能是私有的,需要修改构造的修饰符
}
final Object dInstance = dConstructor.newInstance(100);//根据相应构造的实参生成实例
System.out.println(dInstance);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

/**
* 调用方法
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
*/
public static void invokeMyMethod() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> aClass = MyReflectUtils.class;
//第一步:还是通过Class对象获取声明的方法对象
//方式1.获取所有的公共方法,包括实例方法和静态方法,包括从父类继承的方法
// final Method[] pMethods = aClass.getMethods();
//方式2.通过方法名去获取某个具体的公共方法,注意的是这个方法必须是public修饰的
// final Method pMethod = aClass.getMethod("method_name");
//方式3.获取此类中声明的所有的方法,不包括继承的方法
// final Method[] dMethods = aClass.getDeclaredMethods();
//方式4.通过方法名去获取某个具体的方法,不管这个方法是什么修饰符修饰的
// final Method pMethod = aClass.getDeclaredMethod("method_name",int.class);

//第二步:方法调用
//1.静态方法调用,invoke的obj参数为null
final Method dSMethod = aClass.getDeclaredMethod("testStaticMethod",int.class);
if (!dSMethod.isAccessible()){
dSMethod.setAccessible(true);//修改修饰符才能访问
}
final Object sMInvoke = dSMethod.invoke(null,1);
//2.实例方法的访问
final Method dMethod = aClass.getDeclaredMethod("testPrivateMethod",int.class);
if (!dMethod.isAccessible()){
dMethod.setAccessible(true);//修改修饰符才能访问
}
final Constructor<?> dConstructor = aClass.getDeclaredConstructor();
if (!dConstructor.isAccessible()){
dConstructor.setAccessible(true);
}
final Object dInstance = dConstructor.newInstance();
final Object dMInvoke = dMethod.invoke(dInstance,1);//传入具体的实例对象以调用
}

/**
* 访问属性,和访问方法差不多
* @throws NoSuchFieldException
*/
public static void invokeMyField() throws NoSuchFieldException {
Class<?> aClass = MyReflectUtils.class;
final Field[] pFields = aClass.getFields();
final Field[] dFields = aClass.getDeclaredFields();
final Field aField = aClass.getDeclaredField("a");
if (!aField.isAccessible()){
aField.setAccessible(true);
}
// aField.set(obj,1);
}

private int a;
public int b;

private int testPrivateMethod(int i){
return i;
}

public void testPublicMethod(){

}

private static void testStaticMethod(int i){

}

}