最近在思考组件化结构是的模块之间的通信方式,这时候了解到安居客的方式,所以在深入了解的时候,在涉及到IOC控制反转(Inversion of Control,英文缩写为IoC)时,发现反射这一块我还是整理一下一些方法比较好,所以这里来记录一下。
首先,反射机制是什么呢?
反射指的是可以于运行时加载,探知和使用编译期间完全未知的类
反射有什么用?
程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性
和方法; 对于任意一个对象,都能调用他的任意一个方法和属性。
每个类被加载进入内存之后,系统就会为该类生成一个对应的java.lang.Class对象,通过该Class对象就可以访
问到JVM中的这个类
反射使用时需要了解的类:
java.lang.Class; //类
java.lang.reflect.Constructor; //构造器
java.lang.reflect.Field;//变量
java.lang.reflect.Method;//方法
java.lang.reflect.Modifier;//修饰符,如public、static
然后是这些类如何去使用
首先来定义一个用于测试的类:
public class TesteflexR{
int a = 0;
TesteflexR(){
}
TesteflexR(int type){
}
public void getInt(){
}
public void getDouble(int s){
}
}
类的获取方式有三种
//第一种方式:
Classc1 = Class.forName("TesteflexR");
//第二种方式:
//java中每个类型都有class属性.
Classc2 = TesteflexR.class;
//第三种方式:
//java语言中任何一个java对象都有getClass方法
TesteflexR e = new TesteflexR();
Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是TesteflexR)
然后在获取到类之后,我们就可以获取到更多的数据
1、实例化对象
//实例化这个类赋给o
Object o = e.newInstance();
2、实例化属性
Field[] fields = e.getFields();//获取所有属性
Field fielda = e.getField("a");//获取a属性
fielda.set(e,1);//给act对象中的a变量赋值为1
fielda.getInt(e);//获取act对象中的a变量的值
3、实例化构造器
//构造器部分ß
Constructor[] constructors = e.getDeclaredConstructors();//获取所有构造方式
Constructor constructor = e.getDeclaredConstructor();//获取构造器,传入参数的话则是获取指定的有参数的构造器
Constructor constructori = e.getDeclaredConstructor(Integer.class);//获取构造器,传入参数的话则是获取指定的有参数的构造器
esteflexR reflex1 = (TesteflexR) constructor.newInstance();//用构造器来新建对象
4、实例化方法
Method[] methods = e.getDeclaredMethods();//获取所有方法
Method methodGetInt = e.getDeclaredMethod("getInt");//获取getInt()方法
Method methodGetDouble = e.getDeclaredMethod("getDouble",Integer.class);//获取getDouble方法,这个方法需要传入一个int类型的值
methodGetInt.invoke(e);//执行getInt方法,不需要传入参数
methodGetDouble.invoke(e,6);//执行getDouble方法,需要传入参数6
5、修饰词
Log.d("modifier",Modifier.toString(act.getModifiers()) + "class " + act.getSimpleName());//返回类的修饰词
Log.d("modifier",Modifier.toString(fielda.getModifiers()) + "int " + fielda.getName());//返回类的修饰词
Log.d("modifier",Modifier.toString(methodGetInt.getModifiers()) + "void " + methodGetInt.getName());//返回类的修饰词
基本方法清楚了,然后来一次实践,以Activity的setContentView为例
public void test(Activity activity){
Class<? extends Activity> clazz = activity.getClass();//获取Activity的类
try
{
Method method = clazz.getMethod("setContentView",int.class);//通过反射获取方法
method.setAccessible(true);//setAccessible(true)可以访问private域,并且可以提升反射速度
method.invoke(activity, R.layout.main_layout);//调用activity对象的METHOD_SET_CONTENTVIEW方法,传入的参数为contentViewLayoutId
} catch (Exception e)
{
e.printStackTrace();
}
}
唔,这个例子当然没有所有方法都用到,不过基本的使用就到这里了,其他的自己试吧
最后还有一点做一下记录
我在Android Studio中尝试了在Library中用反射调用application中的类的方法,结果调用成功了,可见路由+IOC的确是可以实现从底层路由的