JAVA的内省机制(introspector)与反射机制(reflection)

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

Java代码 复制代码  收藏代码
  1. package MyTest;   
  2. public class bean {   
  3.         private String id = null ;   
  4.         private String name = null ;   
  5.   
  6.         public String getId() {   
  7.                 return id;   
  8.         }   
  9.         public void setId(String id) {   
  10.                 this.id = id;   
  11.         }   
  12.   
  13.         public String getName() {   
  14.                 return name;   
  15.         }   
  16.         public void 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. public class 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.   public static void main(String[] args)       
  144.   {      
  145.    new myBeanIntrospector();      
  146.   }      
  147. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值