java——-反省机制(代码例子)-

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

package MyTest;     
public class bean {     
        private String id = null ;     
        private String name = null ;     
    
        public String getId() {     
                return id;     
        }     
        public void setId(String id) {     
                this.id = id;     
        }     
    
        public String getName() {     
                return name;     
        }     
        public void setName(String name) {     
                this.name = name;     
        }     
}     
    
package MyTest;     
import java.beans.BeanInfo;     
import java.beans.EventSetDescriptor;     
import java.beans.Introspector;     
import java.beans.MethodDescriptor;     
import java.beans.PropertyDescriptor;     
import java.lang.reflect.Method;     
public class myBeanIntrospector {     
public myBeanIntrospector()        
  {        
   try       
   {        
    //实例化一个Bean        
    bean beanObj = new bean();        
    //依据Bean产生一个相关的BeanInfo类        
    BeanInfo bInfoObject =         
    Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());        
    //定义一个用于显示的字符串        
    String output = "";        
        
    //开始自省        
          
    /*     
    * BeanInfo.getMethodDescriptors()     
    * 用于获取该Bean中的所有允许公开的成员方法,以MethodDescriptor数组的形式返回     
    *     
    * MethodDescriptor类     
    * 用于记载一个成员方法的所有信息     
    * MethodDescriptor.getName()     
    * 获得该方法的方法名字     
    * MethodDescriptor.getMethod()     
    * 获得该方法的方法对象(Method类)     
    *     
    * Method类     
    * 记载一个具体的的方法的所有信息     
    * Method.getParameterTypes()     
    * 获得该方法所用到的所有参数,以Class数组的形式返回     
    *     
    * Class..getName()     
    * 获得该类型的名字     
    */       
    output = "内省成员方法:/n";        
    MethodDescriptor[] mDescArray = bInfoObject.getMethodDescriptors();        
    for (int i=0;i<mDescArray.length ;i++ )        
    {        
     //获得一个成员方法描述器所代表的方法的名字        
     String methodName = mDescArray[i].getName();        
             
     String methodParams = new String();        
     //获得该方法对象        
     Method methodObj = mDescArray[i].getMethod();        
     //通过方法对象获得该方法的所有参数,以Class数组的形式返回        
     Class[] parameters = methodObj.getParameterTypes();        
     if (parameters.length>0)        
     {        
      //获得参数的类型的名字        
      methodParams = parameters[0].getName();        
      for (int j=1;j<parameters.length ;j++ )        
      {        
       methodParams = methodParams + "," + parameters[j].getName();        
      }        
     }        
     output += methodName + "(" + methodParams + ")/n";        
    }        
    System.out.println(output);        
          
    /*     
    * BeanInfo.getPropertyDescriptors()     
    * 用于获取该Bean中的所有允许公开的成员属性,以PropertyDescriptor数组的形式返回     
    *     
    * PropertyDescriptor类     
    * 用于描述一个成员属性     
    *     
    * PropertyDescriptor.getName()     
    * 获得该属性的名字     
    *     
    * PropertyDescriptor.getPropertyType()     
    * 获得该属性的数据类型,以Class的形式给出     
    *     
    */       
    output = "内省成员属性:/n";        
    PropertyDescriptor[] mPropertyArray = bInfoObject.getPropertyDescriptors();        
    for (int i=0;i<mPropertyArray.length ;i++ )        
    {        
     String propertyName = mPropertyArray[i].getName();        
     Class propertyType = mPropertyArray[i].getPropertyType();        
     output += propertyName + " ( " + propertyType.getName() + " )/n";        
    }        
    System.out.println(output);        
          
        
    /*     
    * BeanInfo.getEventSetDescriptors()     
    * 用于获取该Bean中的所有允许公开的成员事件,以EventSetDescriptor数组的形式返回     
    *     
    * EventSetDescriptor类     
    * 用于描述一个成员事件     
    *     
    * EventSetDescriptor.getName()     
    * 获得该事件的名字     
    *     
    * EventSetDescriptor.getListenerType()     
    * 获得该事件所依赖的事件监听器,以Class的形式给出     
    *     
    */       
    output = "内省绑定事件:/n";        
    EventSetDescriptor[] mEventArray = bInfoObject.getEventSetDescriptors();        
    for (int i=0;i<mEventArray.length ;i++ )        
    {        
     String EventName = mEventArray[i].getName();        
     Class listenerType = mEventArray[i].getListenerType();        
     output += EventName + "(" + listenerType.getName() + ")/n";        
    }        
    System.out.println(output);        
    System.out.println("write by esonghui :");        
          
   }        
   catch (Exception e)        
   {        
    System.out.println("异常:" + e);        
   }        
  }        
  public static void main(String[] args)         
  {        
   new myBeanIntrospector();        
  }        
}    

猜你喜欢

转载自my.oschina.net/u/3805464/blog/1814038