Java 内省机制


Java 内省机制

内省(introspector)这个词,就翻译上来说,还真是不太好理解,也不太好意译,总之我觉得只要把它当作是一种约定俗成的叫法就好,更重要的是理解它的实现机制。

1.   JavaBean

JavaBean是内省机制中重要的一员,它是内省机制操作的对象,它也是Java类,只是遵循了某种约定写法的Java类,它里面包含了私有的(private)的属性及这些属性对应的Setter和Getter方法,它对数据进行了封装,对应了一定的业务逻辑;JavaBean和POJO(PlainOrdinary Java Object,即简单的Java对象)很像,但又不完全一样。例如下面一个类就是一个JavaBean:

package learn.introspector;
 
public class Person {
       private String name;
       private int age;
       private String ID;
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public int getAge() {
              return age;
       }
       public void setAge(int age) {
              this.age = age;
       }
       public String getID() {
              return ID;
       }
       public void setID(String ID) {
              this.ID = ID;
       }
}


 

这个类并没有实现任何的额外功能,知识对其内部的成员进行了一些简单的操作,我们把符合这个规范的类就叫做JavaBean。

2.   内省机制包含的类

1)        既然内省是对JavaBean的操作,那肯定有对应JavaBean属性的类,它就是属性描述器(PropertyDescriptor),它通常会和反射机制一同使用。

2)        Introspector类,它可以把一个类看作是JavaBean,通过getBeanInfo()方法获得这个类的信息。

通过以上两种都可以获得JavaBean的信息,上面的描述可能不是特别好理解,还是来看一下代码比较好理解:

通过PropertyDescriptor类:

package learn.introspector;
 
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
/**
 * Person类
 * JavaBean
 */
class Person {
       private String name;
       private int age;
       private String ID;
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public int getAge() {
              return age;
       }
       public void setAge(int age) {
              this.age = age;
       }
       public String getID() {
              return ID;
       }
       public void setID(String ID) {
              this.ID = ID;
       }
}
 
 
public class IntrospectorDemo{
       /**测试
        * @throws IntrospectionException
        * @throws InvocationTargetException
        * @throws IllegalArgumentException
        * @throws IllegalAccessException */
       public static void main(String args[]) throws IntrospectionException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {
              /*创建JavaBean实例,并赋值*/
              Person person=new Person();
              person.setName("李明");
              person.setAge(15);
              person.setID("1");
              /*创建name属性描述器*/
              PropertyDescriptor propertyDescriptor=new PropertyDescriptor("name", person.getClass());
              /*获得person的getName()方法的Method对象*/
              Method methodGetName=propertyDescriptor.getReadMethod();
              /*打印mathodGetName的调用结果,相当于执行了person的getName()方法*/
              System.out.println(methodGetName.invoke(person));
             
              /*获得person的setName()方法的Method对象*/
              Method methodSetName=propertyDescriptor.getWriteMethod();
              /*打印mathodSetName的调用结果,相当于执行了person的setName()方法*/
              methodSetName.invoke(person, "王五");
              System.out.println(methodGetName.invoke(person));
             
       }
}
 


通过Introspector类:

package learn.introspector;
 
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
importjava.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
/**
 *Person类
 *JavaBean
 */
class Person {
         privateString name;
         privateint age;
         privateString ID;
         publicString getName() {
                   returnname;
         }
         publicvoid setName(String name) {
                   this.name= name;
         }
         publicint getAge() {
                   returnage;
         }
         publicvoid setAge(int age) {
                   this.age= age;
         }
         publicString getID() {
                   returnID;
         }
         publicvoid setID(String ID) {
                   this.ID= ID;
         }
}
 
public class IntrospectorDemo{
         /**测试
          * @throws IntrospectionException
          * @throws InvocationTargetException
          * @throws IllegalArgumentException
          * @throws IllegalAccessException */
         publicstatic void main(String args[]) throws IntrospectionException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {
                   /*创建JavaBean实例,并赋值*/
                   Personperson=new Person();
                   person.setName("李明");
                   person.setAge(15);
                   person.setID("1");
        
                   BeanInfobeanInfo=Introspector.getBeanInfo(person.getClass());
                   /*BeanInfo不能直接获取到对应的属性描述器,只能获取所有的属性描述器*/
                   PropertyDescriptorpropertyDescriptors[]=beanInfo.getPropertyDescriptors();
                   /*循环判断是不是我们需要使用的属性描述器*/
                   PropertyDescriptorneedDescriptor=null;
                   for(PropertyDescriptorpd:propertyDescriptors) {
                            /*判断是不是我们需要的属性描述器*/
                            if("name".equals(pd.getName())) {
                                     needDescriptor=pd;
                                     break;
                            }
                   }
                   /*获得person的setName()方法的Method对象*/
                   MethodmathodSetName=needDescriptor.getWriteMethod();
                   MethodmethodGetName=needDescriptor.getReadMethod();
                   /*打印mathodSetName的调用结果,相当于执行了person的setName()方法*/
                   mathodSetName.invoke(person,"王五");
                   System.out.println(methodGetName.invoke(person));
         }
}


 

程序输出:

 

李明
王五
 


一般,内省和反射都会结合使用,而且很多的Java框架都通用到了内省,比如Struts等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值