黑马程序员_反射
来源:互联网 发布:mac. 压缩软件 编辑:程序博客网 时间:2024/04/29 02:18
------- android培训、java培训、期待与您交流! ----------
反射reflect
开发步骤
获得所要操作的类的文件字节码文件对象
方法一:利用Class类的forName()方法获取
例:Class clazz =Class.forName("com.luolei.Person");
该方法返回的是一个类的字节码文件对象
注意传入的是类的完整路劲;包括包名
开发一般用这种方法;扩展性最好,
方法二:通过类的静态.class属性来获取
例:Class clazz=Person.class;
这种方法通过Object的.class也可以获取到文件的字节码对象;
但是这种方式前提是你要知道别人所实现你接口的类名
所以这种方式看是代码简单,但却没有扩展性或扩展性极差
方法三:通过类的getClass()方法来获取
例:Class clazz=new Person.getClass();
这种方式需要一个类的对象,
试想一下,你连别人创建什么类名你都不知道,你如何获取对象
所以扩展性也极差
说下这个方法的原理
我们都知道万物皆对象,一个类也不例外,它也是对象
它就是类这个类的对象
而我们所写的程序都是以文件字节码的形式存在的,所以object有了一个静态的。class属性和一个getClass()
所以二三方法就是利用object而创建了该类的文件字节码对象
有了这这文件的字节码文件,那么我们要创建该类的对象
对于无参的构造函数用newInstance()返回该类的一个对象
例:Person person = (Preson)class.newInstance();
该方法返回的是一个无参的构造函数的对象
对于有参的构造函数用该类字节码文件的getConstructor()返回一个构造器对象(构造函数的类)然后用构造器的newInstance(参数)创建对象
例:Person person = clazz.getConstructor(String.class,int.class).newInstance("罗磊",20);
为何是String.class呢?
原因是:不管什么类型都可以用其对应的字节码文件所描述
现在我们要访问该类的成员变量
一,有了字节码文件对象啦,可以直接掉用clazz.getField("age")返回一个Field(变量)对象
但这种方法只实用于该变量是public权限的
二,用clazz.getDeclaredField(“age”)返回一个变量(Field)对象
这个方法能访问到所有权限的变量
然而要是想要操纵该变量,则需要用到该类对象clazz.getDeclaredField("age").get(clazz.newInstance())
但我们要操纵的变量是private时 可以用field.setAccessible();(强爆这个类,就是强行操作)
访问与操作方法
一般方法的访问与调用
调用clazz.getMethod(“操作的方法名”,String.class,int.class(传入参数的类型))返回一个方法类对象Method
该对象调用的invoke(“上面创建的类对象”,“小强”,56)就可以掉用操作的类的上面指定的方法
对于私有的方法
操作和一般方法一样 只是将getMethod改成getDeclaredField 然后用的时候要先用setAccess强暴一下
静态方法
操作与一般方法一致,只是调用方法时不用传入对象
main方法
invoke(“要操作的类的对象”,(Object)Stirng【】{“abd”,“撒旦法”})
因为1.4版本时没有引入可变参数的概念,所以如果需要多个参数时就会用数组进行装载,而jdk在调用时会将这些数组中的元素拆分,
所以会将上面的String[]拆分成两个String 参数传入main方法,而程序并没有操作两个string参数的main方法所以会报错,
解决办法:将String强转成Object 让jdk误认为是传入一个对象,也就恰好达到我们想要传如多元素的数组的效果
还有一种解决:new Object【】{String【】{“abd”,“斯蒂芬”}}封装给虚拟机拆,也能拆到我们想要的结果
用途
框架的开发用到
如:我们可以定义一个接口
让接口具有某些方法或属性
然后在我们的框架里调用这些方法或属性
然而你却不知道别人会为你这个接口写一个什么样的名字的类
所以可以在框架中定义好反射机制
通过反射机制和配置文件相关联
只要在配置文件中告诉框架所调用的类名,方法,属性即可
反射机制会获取配置文件中的类名,方法名。。。。
不管别人写什么类,只要实现了接口的方法就可以在框架的程序中运行
例:就像Eclipse 自己没有图形化界面的操作,然而只要我们导入相应的包,Eclipse就能有相关的功能
内省(反射的特例)
开发步骤
调用getBeanInfo(Class<?> beanClass, Class<?> stopClass) 方法返回一个BeanInfo接口对象来省给进去的bean类,他会把bean的所有属性封装到beaninfo对象中,拿到这个beaninfo对象相当于拿到bean的所有属性
例:BeanInfo beaninfo = Introspector .getBeanInfo( Person, Object);
拿到这个beanifo对象后接着调用该对象的getPropertyDescriptors()就可以拿到每一个属性的属性描述器,该方法返回一个属性描述器数组PropertyDescriptor[]
PropertyDescriptor[] pds = beaninfo.getPropertyDescriptors()
for( PropertyDescriptor pd : pds){ 可以得到每一个属性对象 }
拿到属性描述器后再调用该描述器的getReadMethod()就可以得到这个bean的get值
PropertyDescriptor pd = new PropertyDescriptor(“name”,Person.class);
Method method = pd.getWriteMethod()
method.invoke("P(创建要操作的对象)",“罗磊”);
用于给Bean对象反射
开发现在多用BeanUtils
开发步骤
一,导包
导入beanutils 的jar包
而beanutils工作过程需要个日志记录器的支持,所以还需导入log4j中的Commons-logging。jar
然后直接调用BeanUtils.setproperty(“需要操作的bean的对象”,“需要操作的属性名”,“传入的值”);
由于beanutils 会自动将类型转为bean所需的类型,但这只能支持8种基本数据类型
如果不是8种基本数据类型可一参阅java基础加强的18集
------- android培训、java培训、期待与您交流! ----------
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 走技术线,还是技术管理线?
- 扫描MAC,IP,计算机名
- ORA-12516: TNS: 监听程序无法找到匹配协议栈的可用句柄
- 使用选择器
- 一道Intel的笔试题
- 黑马程序员_反射
- oracle 删除重复数据
- LeetCode Partition List
- 大站技术
- 使用WSASend改善网络程序的性能
- word中 两页同时并排显示 与 单页显示 之间的切换
- 树(此处以二叉搜索树为例)的按层遍历 更改版本
- POJ 2251 Dungeon Master
- hdu 1198 深搜