0


内省 Introspector详解

概念

JavaBean

  • 属性是私有的;
  • 有无参的public构造方法;
  • 对私有属性提供public的getXxx方法和setXxx方法; 符合这些特征的类,被称为JavaBean;而JDK提供了一套API用来访问某个属性的getter/setter方法,这些API存放在java.beans中,这就是内省。

内省与反射的关系

  • 一个类有两种状态(编译和运行),通常我们是在编译状态来获取类的信息,也就是new一个实例出来,然后通过该实例来获取类内部的信息。若需要在类运行时动态的获取类的信息,则需要用到反射。
  • 反射是在运行中,对任意一个类,能够获取到这个类所有的属性和方法。
  • 内省是通过反射来实现的,用BeanInfo来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性,其包括的主要类有:Introspector、BeanInfo、PropertyDescriptor
  • 内省对javaBean属性、方法的处理方式。
  • 反射可以操作各种类的属性,而内省只是通过反射来操作JavaBean的属性;
  • 内省设置属性值会调用setter方法,而反射可以直接调用Field;
  • 反射看到.class的所有,看到的是客观事实,而内省更像是主观的判断,比如看到getName()内省就会认为这个类有name字段,但实际上不一定有name。
  • 通过内省可以获取到bean的getter和setter。

核心API

在这里插入图片描述

  • Introspector提供了一系列的getBeanInfo 方法,可以拿到一个JavaBean的所有核心信息。
  • 通过BeanInfo的getPropertyDescriptors和getMethodDescription方法可以拿到JavaBean的字段信息列表和getter和setter的方法列表。
  • PropertyDescriptors 可以根据字段直接获得该字段的 getter 和 setter 方法。
  • MethodDescriptors 可以获得方法的元信息,比如方法名,参数个数,参数字段类型等。
  • PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:1. getPropertyType(),获得属性的Class对象;2. getReadMethod(),获得用于读取属性值的方法;getWriteMethod(),获得用于写入属性值的方法;3. hashCode(),获取对象的哈希值;4. setReadMethod(Method readMethod),设置用于读取属性值的方法;5. setWriteMethod(Method writeMethod),设置用于写入属性值的方法。

示例

  • JavaBean
/**
 * 部门
 * @author HC
 *
 */publicclassDept{/**
     * 部门编号
     */privateInteger deptno;/**
     * 部门名称
     */privateString dname;/**
     * 部门地址
     */privateString loc;publicDept(){}publicDept(Integer deptno,String dname,String loc){this.deptno = deptno;this.dname = dname;this.loc = loc;}publicIntegergetDeptno(){return deptno;}publicvoidsetDeptno(Integer deptno){this.deptno = deptno;}publicStringgetDname(){return dname;}publicvoidsetDname(String dname){this.dname = dname;}publicStringgetLoc(){return loc;}publicvoidsetLoc(String loc){this.loc = loc;}@OverridepublicStringtoString(){return"Dept{"+"deptno="+ deptno +", dname='"+ dname +'\''+", loc='"+ loc +'\''+'}';}}
  • 测试方法
publicstaticvoidmain(String[] args)throwsIntrospectionException{// 获取整个Bean的信息// BeanInfo beanInfo= Introspector.getBeanInfo(user.getClass());// 在Object类时候停止检索,可以选择在任意一个父类停止BeanInfo beanInfo =Introspector.getBeanInfo(Dept.class,Object.class);System.out.println("所有属性描述:");// 获取所有的属性描述PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();for(PropertyDescriptor pd : pds){System.out.println(pd.getName());}System.out.println("所有方法描述:");MethodDescriptor[] mds = beanInfo.getMethodDescriptors();for(MethodDescriptor md : mds){System.out.println(md.getName());}}

说明:

  • getPropertyDescriptors(),获得属性的描述,可以采用遍历BeanInfo的方法,来查找、设置类的属性。
  • 结果在这里插入图片描述
  • 测试代码
publicstaticvoidmain(String[] args)throwsIntrospectionException,InvocationTargetException,IllegalAccessException{Dept dept =newDept(10,"sales","NewYork");BeanInfo beanInfo =Introspector.getBeanInfo(Dept.class);//获取属性描述符PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();for(PropertyDescriptor pd : pds){System.out.println(pd.getName()+"="+ pd.getReadMethod().invoke(dept));}PropertyDescriptor dname =newPropertyDescriptor("dname",Dept.class);System.out.println("内省获取的dname为:"+ dname.getReadMethod().invoke(dept));//修改属性的值
    dname.getWriteMethod().invoke(dept,"research");System.out.println("内省修改的dname为:"+ dept.getDname());}
  • 结果在这里插入图片描述
标签: 内省 Introspector

本文转载自: https://blog.csdn.net/lianghecai52171314/article/details/124195281
版权归原作者 梁云亮 所有, 如有侵权,请联系我们删除。

“内省 Introspector详解”的评论:

还没有评论