Java内省

内省的简单操作(Introspector

1.      JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则

2.      如果要在两个模板之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。去掉set或者get前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小写的。总之,一个类被当做javabean使用时,javabean的属性是根据方法名推断出来的,它根本看不到java类的内部成员变量。

3.      一个符合javabean特点的类可以当做一个普通类一样,但把它当做javabean用肯定需要带来一些额外的好处。如下:

在java EE开发中,经常要使用到javabean。很多环境就要求按javabean方式进行操作

JDK中提供了对javabean进行操作的一些api,这套api称为内省。如果要你自己去通过getX方法来方位私有的想,怎么做?有一定的难度,所以用用内省这套api操作javabean比用普通类的方式更为方便。

 

以下是采用的是顺序的写法

 

import java.beans.PropertyDescriptor;

import java.lang.reflect.Method;

 

publicclassIntrospectorDemo1 {

 

   publicstaticvoid main(String[] args)throws Exception {

      ReflectPointrp = newReflectPoint(3, 5);

     

      StringpropertyName = "x";

      //内省的api,属性标记

      PropertyDescriptorpd = newPropertyDescriptor(propertyName, rp.getClass());

      //得到x的读方法,也就是get方法

      MethodmethodGetX = pd.getReadMethod();

      //不清楚返回值的类型,所以使用Object,执行invoke方法

      ObjectretVal = methodGetX.invoke(rp);

      System.out.println(retVal);

     

      PropertyDescriptorpd2 = newPropertyDescriptor(propertyName, rp.getClass());

      MethodmethodSetX = pd2.getWriteMethod();

      methodSetX.invoke(rp,8);

     

      //使用普通类的方法来打印数据,为了简便,以上是使用内省

      System.out.println(rp.getX());

   }

 

}

 

//将以上的代码抽取为方法

import java.beans.PropertyDescriptor;

import java.lang.reflect.Method;

 

publicclassIntrospectorDemo1 {

 

   publicstaticvoid main(String[] args)throws Exception {

      ReflectPointrp = newReflectPoint(3, 5);

     

      //此变量时表示需要获取的是哪个字段

      /**

       * 如果不采用内省,则会使用

       * x -> X -> getX-> methodGetX->

       */

      StringpropertyName = "x";

     

      //内省的api,属性标记

      ObjectretVal = getProperty(rp, propertyName);

      System.out.println(retVal);

     

     

      Objectvalue = 8;

      setProperty(rp,propertyName, value);

     

      //使用普通类的方法来打印数据,为了简便,以上是使用内省

      System.out.println(rp.getX());

   }

   /**

    *

    * @param rp         javabean的那个类

    * @param propertyName     javabean中需要操作的数据(xy

    * @param value         需要更改的javabean中的数据

    * @throws IntrospectionException

    * @throws IllegalAccessException

    * @throws InvocationTargetException

    */

   privatestaticvoidsetProperty(ReflectPoint rp, String propertyName,

         Objectvalue) throwsIntrospectionException,

         IllegalAccessException,InvocationTargetException {

      PropertyDescriptorpd2 = newPropertyDescriptor(propertyName, rp.getClass());

      MethodmethodSetX = pd2.getWriteMethod();

      methodSetX.invoke(rp,value);

   }

   /**

    *

    * @param rp         javabean的那个类

    * @param propertyName     javabean中需要操作的数据(xy

    * @return

    * @throws IntrospectionException

    * @throws IllegalAccessException

    * @throws InvocationTargetException

    */

   privatestatic ObjectgetProperty(Object rp, String propertyName)

         throws IntrospectionException,IllegalAccessException,

         InvocationTargetException{

      PropertyDescriptorpd = newPropertyDescriptor(propertyName, rp.getClass());

      //得到x的读方法,也就是get方法

      MethodmethodGetX = pd.getReadMethod();

      //不清楚返回值的类型,所以使用Object,执行invoke方法

      ObjectretVal = methodGetX.invoke(rp);

      return retVal;

   }

 

}

 

 

内省的复杂操作

以上是较为简单的一种方法,还有一种更为复杂的方法,通过beaninfo来得到需要操作的对象

   privatestatic ObjectgetProperty1(Objectrp, String propertyName)

         throws IntrospectionException, IllegalAccessException,

         InvocationTargetException {

      ObjectretVal = null;

      //Introspector这个类中有一个方法getBeanInfo可以返回javabean类的一个beaninfo

      //数据,通过beaninfo来得到需要内省的属性描述,返回的是一个PropertyDescriptor的数组

      //然后在找到需要内省的那个字段(x),进而在得到那个字段的getReadMethod(也就是get方法)

      //最后在执行那个方法,得到所需要的数据

      BeanInfobeanInfo = Introspector.getBeanInfo(rp.getClass());

      PropertyDescriptor[]pds = beanInfo.getPropertyDescriptors();

      for(PropertyDescriptor pd:pds) {

         if(pd.getName().equals(propertyName)){

            MethodmethodGetX = pd.getReadMethod();

            retVal= methodGetX.invoke(rp);

            break;

         }

      }

      return retVal;

   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值