2 对基本反射语法的封装
前面介绍的种种语法,无论是反射出一个类,还是反射出一个构造函数井调用它,都是为了进一步读写类的方法和宇段,所以我们只要封装以下几个方法即可:
- 反射出 一个构造 函数并调用它 。
- 调用静态方法。
- 调用实例方法 。
- 获取和设置一个字段的值。
- 对泛型的处理 。
2.1 反射出一个构造函数
public static Object createObject(String className, Class[] pareTyples, Object[] pareVaules) {
try {
Class r = Class.forName(className);
Constructor ctor = r.getDeclaredConstructor(pareTyples);
ctor.setAccessible(true);
return ctor.newInstance(pareVaules);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
final String className = "xxx.xxx.TestClassCtor";
Class r = Class.forName(className);
//含参
Class[] p3 = {int.class, String.class};
Object[] v3 = {1, "bjq"};
Object obj = RefInvoke.createObject(className, p3, v3);
//无参
Object obj2 = RefInvoke.createObject(className, null, null);
2.2 调用实例方法
public static Object invokeInstanceMethod(Object obj, String methodName, Class[] pareTyples, Object[] pareVaules) {
if(obj == null)
return null;
try {
//调用一个private方法
Method method = obj.getClass().getDeclaredMethod(methodName, pareTyples); //在指定类中获取指定的方法
method.setAccessible(true);
return method.invoke(obj, pareVaules);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//3.1.获取类的private实例方法,调用它
public void test3() {
try {
//创建一个对象
Class[] p3 = {int.class, String.class};
Object[] v3 = {1, "bjq"};
Object obj = RefInvoke.createObject(className, p3, v3);
//调用一个private方法
Class[] p4 = {String.class};
Object[] v4 = {"jianqiang"};
Object result = RefInvoke.invokeInstanceMethod(obj, "doSomething", p4, v4);
Object a = result;
} catch (Exception e) {
e.printStackTrace();
}
}
2.3 调用静态方法
public static Object invokeStaticMethod(String className, String method_name, Class[] pareTyples, Object[] pareVaules) {
try {
Class obj_class = Class.forName(className);
Method method = obj_class.getDeclaredMethod(method_name, pareTyples);
method.setAccessible(true);
return method.invoke(null, pareVaules);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//3.2.获取类的private静态方法,调用它
public void test3_1() {
try {
Class[] p3 = {};
Object[] v3 = {};
RefInvoke.invokeStaticMethod(className, "work", p3, v3);
} catch (Exception e) {
e.printStackTrace();
}
}
2.4 获取并设置一个字段的值
public static Object getFieldObject(String className, Object obj, String filedName) {
try {
Class obj_class = Class.forName(className);
Field field = obj_class.getDeclaredField(filedName);
field.setAccessible(true);
return field.get(obj);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void setFieldObject(String classname, Object obj, String filedName, Object filedVaule) {
try {
Class obj_class = Class.forName(classname);
Field field = obj_class.getDeclaredField(filedName);
field.setAccessible(true);
field.set(obj, filedVaule);
} catch (Exception e) {
e.printStackTrace();
}
}
//4.1.获取类的private实例字段,修改它
public void test4() {
try {
//创建一个对象
Class[] p3 = {int.class, String.class};
Object[] v3 = {1, "fhx"};
Object obj = RefInvoke.createObject(className, p3, v3);
//获取name字段,private
Object fieldObject = RefInvoke.getFieldObject(className, obj, "name");
//只对obj有效
RefInvoke.setFieldObject(className, obj, "name", "hongxue123");
Object fieldObject2 = RefInvoke.getFieldObject(className, obj, "name");
int a = 1;
} catch (Exception e) {
e.printStackTrace();
}
}
//获取类的private静态字段,修改它
public void test4_1() {
try {
Object fieldObject = RefInvoke.getFieldObject(className, null, "address");
RefInvoke.setFieldObject(className, null, "address", "ABCD");
//静态变量,一次修改,终生受用
TestClassCtor.printAddress();
} catch (Exception e) {
e.printStackTrace();
}
}
2.5 对泛型类的处理
public class AMN {
private static final Singleton<ClassB2Interface> gDefault = new Singleton<ClassB2Interface>() {
protected ClassB2Interface create() {
ClassB2 b2 = new ClassB2();
b2.id = 2;
return b2;
}
};
static public ClassB2Interface getDefault() {
return gDefault.get();
}
}
class ClassB2 implements ClassB2Interface{
public int id;
public void doSomething() {
Log.v("hongxue", "ClassB2 doSomething");
}
}
public interface ClassB2Interface {
void doSomething();
}
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
public void test5() {
try {
//获取AMN的gDefault单例gDefault,gDefault是静态的
Object gDefault = RefInvoke.getFieldObject("xxx.xxx.xxx.AMN", null, "gDefault");
// gDefault是一个 android.util.Singleton对象; 我们取出这个单例里面的mInstance字段
Object rawB2Object = RefInvoke.getFieldObject(
"xxx.xxx.xxx.Singleton",
gDefault, "mInstance");
// 创建一个这个对象的代理对象ClassB2Mock, 然后替换这个字段, 让我们的代理对象帮忙干活
Class<?> classB2Interface = Class.forName("xxx.xxx.xxx.ClassB2Interface");
Object proxy = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] { classB2Interface },
new ClassB2Mock(rawB2Object));
//把Singleton的mInstance替换为proxy
RefInvoke.setFieldObject("xxx.xxx.xxx.Singleton", gDefault, "mInstance", proxy);
} catch (Exception e) {
e.printStackTrace();
}
}
2.6 RefInvoke.java
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class RefInvoke {
public static Object createObject(String className, Class[] pareTyples, Object[] pareVaules) {
try {
Class r = Class.forName(className);
Constructor ctor = r.getDeclaredConstructor(pareTyples);
ctor.setAccessible(true);
return ctor.newInstance(pareVaules);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Object invokeInstanceMethod(Object obj, String methodName, Class[] pareTyples, Object[] pareVaules) {
if(obj == null)
return null;
try {
//调用一个private方法
Method method = obj.getClass().getDeclaredMethod(methodName, pareTyples); //在指定类中获取指定的方法
method.setAccessible(true);
return method.invoke(obj, pareVaules);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Object invokeStaticMethod(String className, String method_name, Class[] pareTyples, Object[] pareVaules) {
try {
Class obj_class = Class.forName(className);
Method method = obj_class.getDeclaredMethod(method_name, pareTyples);
method.setAccessible(true);
return method.invoke(null, pareVaules);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Object getFieldObject(String className, Object obj, String filedName) {
try {
Class obj_class = Class.forName(className);
Field field = obj_class.getDeclaredField(filedName);
field.setAccessible(true);
return field.get(obj);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void setFieldObject(String classname, Object obj, String filedName, Object filedVaule) {
try {
Class obj_class = Class.forName(classname);
Field field = obj_class.getDeclaredField(filedName);
field.setAccessible(true);
field.set(obj, filedVaule);
} catch (Exception e) {
e.printStackTrace();
}
}
}