贯穿整个深圳的
深南大道,也是最繁忙的路,贯穿深圳的几个区,在这条道上有著名的景点和商业圈和IT公司,今天先来腾讯!
什么是反射?
官方一点的解释:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
然而在android中Google很多的类的某些方法不让第三方应用去调用,通过java反射机制能把这些隐藏方法获取出来并调用,三方应用上我们就很方便的去用这些方法。
为什么要使用反射?
优点:
(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
(2)与Java动态编译相结合,可以实现无比强大的功能
(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
(2)与Java动态编译相结合,可以实现无比强大的功能
如果不适用反射,那么你就只能写死到代码里了。
所以说,一个灵活,一个不灵活。
很少情况下是非用反射不可的。大多数情况下反射是为了提高程序的灵活性。
因此一般框架中使用较多。因为框架要适用更多的情况。对灵活性要求较高。
缺点:
(1)使用反射的性能较低
(2)使用反射相对来说不安全
(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性
反射的使用和对比
/** * 通过反射得到对象,知道类的名字,通过方法统一得到对象 * @param name * @return */ public Hero getHeroByReflect(String name) { try { Class<?> cls = Class.forName(name); Hero hero = (Hero) cls.newInstance(); hero.attach(); return hero; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * 通过new的方式得到对象 */ public void getHeroByNew(){ Hero Person = CreateHero("Person"); Person.attach(); } /** * 多个实现类,必须通过判断来区分产出哪个实例 * @param name * @return */ public Hero CreateHero(String name) { if ((name).equals("Children")) { return new Children(); } if ((name).equals("Person")) { return new Person(); } return null; } interface Hero { public void attach(); } //static static class Children implements Hero { //反射需要无参的构造函数,否则异常 //cls.newInstance()默认返回的是Person类的无参数构造对象 // 被反射机制加载的类必须有无参数构造方法,否者运行会抛出异常 public String name; public Children() { } public void setName(String tempName){ name=tempName; } @Override public void attach() { Log.d("Main","Children"); } } class Person implements Hero { @Override public void attach() { Log.d(TAG,"Person"); } }
反射需要掌握的方法:
方法关键字 | 含义 |
---|---|
getDeclareMethods() | 获取所有的方法 |
getReturnType() | 获取方法的返回值类型 |
getParameterTypes() | 获取方法的传入参数类型 |
getDeclareMethod("方法名,参数类型.class,....") | 获得特定的方法 |
- | |
构造方法关键字 | 含义 |
getDeclaredConstructors() | 获取所有的构造方法 |
getDeclaredConstructors(参数类型.class,....) | 获取特定的构造方法 |
- | |
成员变量 | 含义 |
getDeclaredFields | 获取所有成员变量 |
getDeclaredField(参数类型.class,....) | 获取特定的成员变量 |
- | |
父类和父接口 | 含义 |
getSuperclass() | 获取某类的父类 |
getInterfaces() | 获取某类实现的接口
|
/** * 反射常用的的类,方法,变量 */ public void reflectMethod(String name){ try { /** * 类解析 */ Class<?> cls = Class.forName(name);//通过类名加载Children类 // Class<? > clazz = activity.getClass();//通过一个类得到 Hero hero = (Hero) cls.newInstance();//实例化Children Method setname=cls.getDeclaredMethod("setName", String.class);//获取声明的方法setName(),方法名和传值的类型值 setname.invoke(hero, "children");//执行方法,设置调用setName的对象和传入setName的值 /** * 方法解析 */ Method[] methods = cls.getMethods();//得到所有的方法 Method method=methods[0]; method.setAccessible(true);//提高加载的速度,能高20倍 method.invoke(hero, String.class);//方法的执行 /** *方法的参数类型 */ method.getParameterTypes();//获取方法的传入参数类型 method.getReturnType();//获取方法的返回值类型 /** * 变量解析 */ Field[] fields = cls.getFields();//得到所有的成员变量 Field field=fields[0]; field.setAccessible(true);//设置为私有 field.set(cls, "");//给成员变量设置值 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
注意:
cls.newInstance()方法返回的是一个泛型T,我们要强转成Person类
cls.newInstance()默认返回的是Person类的无参数构造对象
被反射机制加载的类必须有无参数构造方法,否者运行会抛出异常
cls.newInstance()方法返回的是一个泛型T,我们要强转成Person类
cls.newInstance()默认返回的是Person类的无参数构造对象
被反射机制加载的类必须有无参数构造方法,否者运行会抛出异常
AS源代码地址:不知道为什么被删了,我会在评论里面把它添加进来