• JAVA的内省机制(introspector)与反射机制(reflection)[转]


    转自:http://yangzhibin-java.javaeye.com/   

          相对而言,反射比内省更容易理解一点。用一句比较白的话来概括,反射就是让你可以通过名称来得到对象 ( 类,属性,方法 ) 的技术,这种技术比内省机制使用范围更广泛。例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值。 内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。
          一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子,这个例子把某个对象的所有属性名称和值都打印出来:

    1 package MyTest;
    2 publicclass bean {
    3 private String id =null ;
    4 private String name =null ;
    5
    6 public String getId() {
    7 return id;
    8 }
    9 publicvoid setId(String id) {
    10 this.id = id;
    11 }
    12
    13 public String getName() {
    14 return name;
    15 }
    16 publicvoid setName(String name) {
    17 this.name = name;
    18 }
    19 }
    20
    21 package MyTest;
    22 import java.beans.BeanInfo;
    23 import java.beans.EventSetDescriptor;
    24 import java.beans.Introspector;
    25 import java.beans.MethodDescriptor;
    26 import java.beans.PropertyDescriptor;
    27 import java.lang.reflect.Method;
    28 publicclass myBeanIntrospector {
    29 public myBeanIntrospector()
    30 {
    31 try
    32 {
    33 //实例化一个Bean
    34 bean beanObj =new bean();
    35 //依据Bean产生一个相关的BeanInfo类
    36 BeanInfo bInfoObject =
    37 Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());
    38 //定义一个用于显示的字符串
    39 String output ="";
    40
    41 //开始自省
    42
    43 /*
    44 * BeanInfo.getMethodDescriptors()
    45 * 用于获取该Bean中的所有允许公开的成员方法,以MethodDescriptor数组的形式返回
    46 *
    47 * MethodDescriptor类
    48 * 用于记载一个成员方法的所有信息
    49 * MethodDescriptor.getName()
    50 * 获得该方法的方法名字
    51 * MethodDescriptor.getMethod()
    52 * 获得该方法的方法对象(Method类)
    53 *
    54 * Method类
    55 * 记载一个具体的的方法的所有信息
    56 * Method.getParameterTypes()
    57 * 获得该方法所用到的所有参数,以Class数组的形式返回
    58 *
    59 * Class..getName()
    60 * 获得该类型的名字
    61 */
    62 output ="内省成员方法:\n";
    63 MethodDescriptor[] mDescArray = bInfoObject.getMethodDescriptors();
    64 for (int i=0;i<mDescArray.length ;i++ )
    65 {
    66 //获得一个成员方法描述器所代表的方法的名字
    67 String methodName = mDescArray[i].getName();
    68
    69 String methodParams =new String();
    70 //获得该方法对象
    71 Method methodObj = mDescArray[i].getMethod();
    72 //通过方法对象获得该方法的所有参数,以Class数组的形式返回
    73 Class[] parameters = methodObj.getParameterTypes();
    74 if (parameters.length>0)
    75 {
    76 //获得参数的类型的名字
    77 methodParams = parameters[0].getName();
    78 for (int j=1;j<parameters.length ;j++ )
    79 {
    80 methodParams = methodParams +","+ parameters[j].getName();
    81 }
    82 }
    83 output += methodName +"("+ methodParams +")\n";
    84 }
    85 System.out.println(output);
    86
    87 /*
    88 * BeanInfo.getPropertyDescriptors()
    89 * 用于获取该Bean中的所有允许公开的成员属性,以PropertyDescriptor数组的形式返回
    90 *
    91 * PropertyDescriptor类
    92 * 用于描述一个成员属性
    93 *
    94 * PropertyDescriptor.getName()
    95 * 获得该属性的名字
    96 *
    97 * PropertyDescriptor.getPropertyType()
    98 * 获得该属性的数据类型,以Class的形式给出
    99 *
    100 */
    101 output ="内省成员属性:\n";
    102 PropertyDescriptor[] mPropertyArray = bInfoObject.getPropertyDescriptors();
    103 for (int i=0;i<mPropertyArray.length ;i++ )
    104 {
    105 String propertyName = mPropertyArray[i].getName();
    106 Class propertyType = mPropertyArray[i].getPropertyType();
    107 output += propertyName +" ( "+ propertyType.getName() +" )\n";
    108 }
    109 System.out.println(output);
    110
    111
    112 /*
    113 * BeanInfo.getEventSetDescriptors()
    114 * 用于获取该Bean中的所有允许公开的成员事件,以EventSetDescriptor数组的形式返回
    115 *
    116 * EventSetDescriptor类
    117 * 用于描述一个成员事件
    118 *
    119 * EventSetDescriptor.getName()
    120 * 获得该事件的名字
    121 *
    122 * EventSetDescriptor.getListenerType()
    123 * 获得该事件所依赖的事件监听器,以Class的形式给出
    124 *
    125 */
    126 output ="内省绑定事件:\n";
    127 EventSetDescriptor[] mEventArray = bInfoObject.getEventSetDescriptors();
    128 for (int i=0;i<mEventArray.length ;i++ )
    129 {
    130 String EventName = mEventArray[i].getName();
    131 Class listenerType = mEventArray[i].getListenerType();
    132 output += EventName +"("+ listenerType.getName() +")\n";
    133 }
    134 System.out.println(output);
    135 System.out.println("write by esonghui :");
    136
    137 }
    138 catch (Exception e)
    139 {
    140 System.out.println("异常:"+ e);
    141 }
    142 }
    143 publicstaticvoid main(String[] args)
    144 {
    145 new myBeanIntrospector();
    146 }
    147 }
  • 相关阅读:
    Ubuntu安装gfortran
    Ubuntu12.04安装vscode i386
    PowerShell让系统可以执行.ps1文件
    Gitlab. Disable user creation on welcome page
    开源项目和工具列表
    布隆过滤器 (Bloom Filter)
    信息系统综合知识概览
    Hadoop实战之四~hadoop作业调度详解(2)
    Hadoop实战之三~ Hello World
    Hadoop实战之二~ hadoop作业调度详解(1)
  • 原文地址:https://www.cnblogs.com/wen12128/p/1989045.html
Copyright © 2020-2023  润新知