zoukankan      html  css  js  c++  java
  • 比反射更强大的技术,内省技术

    比反射更强大的技术,内省技术

    2019-09-07 23:57:41 ZackSock 阅读数 977更多

    在学习Java过程中,总是层层递进的。
    差不多从数据类型到IO、异常就算基础部分(不同书不一样)。
    之后就是Java的进阶,一般我们都会学到泛型、反射之类的。
    今天要说的东西,就和反射有关系,叫做“内省技术”。
    “内省技术”是基于反射技术的,提供了更多的便于操作JavaBean的API。
    一般的话,我们只有学到JavaWeb才会称呼JavaBean,由此可知“内省技术”属于JavaWeb的内容(搞笑逻辑,别介意)。

    1、什么是内省

         前面已经说了,内省就是JDK提供的JavaBean操作的API,基于反射技术。

    2、如何用代码实现内省

         内省使用到的类就是Introspector,说到底学习内省就是学习类Introspecteor类的使用。

    因为内省技术还是比较简单的,下面就直接用代码举例。先创建一个Person类:

    public class Person{
    
    private String name;
    private String sex;
    
    /**
    * 省略get、set方法
    */
    
    public Person(){
    }
    
    }

    类准备好了就可以开始使用内省了。

    第一步:获取BeanInfo对象

    
     
    1. @Test

    2. public void demo(){

    3.  
    4. //调用Introspector中的getBeanInfo()方法,传入要获取信息的类的Class对象

    5. BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);

    6.  
    7. }

    上面的beanInfo就是Person类的完整信息。

    第二步:获得方法描述器和属性描述器

    
     
    1. @Test

    2. public void demo(){

    3.  
    4. //调用Introspector中的getBeanInfo()方法,传入要获取信息的类的Class对象

    5. BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);

    6.  
    7.  
    8. /*********************分割线****************************/

    9.  
    10. //获取方法描述器

    11. MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();

    12.  
    13. //获取属性描述器,调用getPropertyDescriptors方法,返回一个PropertyDescriptor数组

    14. //其中一个PropertyDescriptor代表一个属性

    15. PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

    16.  
    17. }

    之后就可以进行相应的操作了。学过JavaWeb应该都知道,表单有个自动封装数据的功能。其实它的实现就是内省技术,具体就举一个类似的例子。

    要求:把要赋值的数据穿入Map,然后使用方法,把Map中的数据封装到JavaBean当中。

    我们话不多说,直接开始写。依次是:创建Map->给Map赋值->创建对象->把Map中的值传给对象

    
     
    1. @Test

    2. public void demo(){

    3.  
    4. //创建一个Map

    5. Map<String, String> p1 = new HashMap<String, String>();

    6.  
    7. //给Map赋值,其中key为Person中的变量名,value为要赋的值

    8. p1.put("name", "zack");

    9. p1.put("sex", "male");

    10.  
    11. //创建Person对象

    12. Person person = new Person();

    13.  
    14. //给对象赋值,待实现方法

    15. setData2Object(p1, person);

    16. }

    上面使用了一个setData2Object()方法,现在我们来实现一下这个方法:

    
     
    1. private static void setData2Object(Map<String, String> map, Object obj)

    2. throws Exception {

    3. //获取BeanInfo

    4. BeanInfo beanInfo = Introspector.getBeanInfo(person.getClass());

    5.  
    6. //获取属性描述器

    7. PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

    8.  
    9. //遍历描述器

    10. for (PropertyDescriptor descriptor:propertyDescriptors) {

    11.  
    12. //通过属性名去Map中找对应的key

    13. String name = descriptor.getName();

    14.  
    15. //找到对应的key后赋值

    16. if (map.containsKey(name)){

    17. String value = map.get(name);

    18.  
    19. //通过属性描述器获得写入属性的方法

    20. Method writeMethod = descriptor.getWriteMethod();

    21.  
    22. //利用反射设置Value

    23. writeMethod.invoke(person, value);

    24. }

    25. }

    26. }

    里面有一个东西前面没讲,就是通过属性描述器获得写入属性的方法。在api中,属性描述器有两个方法getWriteMethod、getReadMethod。简单来说就是获取get、set方法。之后利用反射就可以了。

    再补充一句,内省属性描述器的个数不是通过属性的个数来算的,而是通过get、set方法。如:setAge、getName就是把前面的set和get去掉,获取一个属性名。

  • 相关阅读:
    Unity Shader入门精要之 screen post-processing effect
    Unity---关于游戏小包的记录
    计算机基础补充之原码、反码、补码
    C#接口实现技巧之借助第三方
    lua中产生 1
    游戏文本本地化(一)
    xlua修复C#的委托事件的时候,需要提前做好配置
    xlua 实现协程替换Unity中的协程
    C#定义只能处理枚举类型的泛型类型
    C# : 泛型的继承关系实现的一个可以存放不同数据类型的链表
  • 原文地址:https://www.cnblogs.com/grj001/p/12223896.html
Copyright © 2011-2022 走看看