黑马程序员——java加强之内省

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、内省

        1、内省对应的英文单词为IntroSpector,英文意思是检查、视察、体检之意,对于程序即对内部进行检查,了解更多的底层细节。

        2、内省的作用:主要针对JavaBean进行操作。

 

二、JavaBean

1、简述:

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

       2)它是一种特殊的Java类,其中的方法符合特殊的规则。只要一个类中含有get或is和set打头的方法,就可以将其当做JavaBean使用。

       3)字段和属性:

            字段就是我们定义的一些成员变量,如private String name;等

            JavaBean的属性是根据其中的setter和getter方法来确定的,而不是依据其中的变量,如方法名为setId,则中文意思是设置Id,getId也是如此;去掉set或者get前缀,剩余部分就是属性名称。如果剩余部分的第二个字母小写,则把剩余部分改为小写。如:getAge/setAge-->age;gettime-->time;setTime-->time;getCPU-->CPU。

       总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。

2、作用:

       如果要在两个模板之间传递多个信息,可将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO),这些信息在类中用私有字段来储存,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。

3、JavaBean的好处:

       一个符合JavaBean特点的类当做普通类一样可以使用,但是把它当做JavaBean类用会带来一些额外的好处:

       1)在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地!

       2)JDK中提供了对JavaBean进行操作的API,这套API称为内省,若要自己通过getX的方式来访问私有x,可用内省这套API,操作JavaBean要比使用普通的方式更方便。

示例:

package cn.itheima.demo;

 

import java.beans.IntrospectionException;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

importjava.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

 

public class IntroSpectorDemo {

         publicstatic void main(String[] args) throws Exception {

                   HashCodeTesthct=new HashCodeTest(2,3);

                   StringpropertyName="x";

                   //"x"-->"X"-->"getX"-->MethodGetX-->

                  

                   //用内省的方式

                   //获取并getX方法

                   Objectretval = getProperty1(hct, propertyName);

                   System.out.println(retval);

                  

                   Objectvalue=5;

                   //获取并调用setX方法

                   setProperty(hct,propertyName, value);

                  

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

         }

         //获取并调用setX方法

         privatestatic void setProperty(HashCodeTest hct, String propertyName,

                            Objectvalue) throws IntrospectionException,

                            IllegalAccessException,InvocationTargetException {

                   PropertyDescriptorpd=new PropertyDescriptor(propertyName,hct.getClass());//创建对象关联

                   MethodmethodSetX=pd.getWriteMethod();//获取JavaBean类中的setX方法

                   methodSetX.invoke(hct,value);//调用setX方法

         }

         //获取并getX方法

         privatestatic Object getProperty1(HashCodeTest hct, String propertyName)

                            throwsIntrospectionException, IllegalAccessException,

                            InvocationTargetException{

                   PropertyDescriptorpd=new PropertyDescriptor(propertyName,hct.getClass());//创建对象关联

                   MethodmethodGetX=pd.getReadMethod();//获取JavaBean类中的getX方法

                   Objectretval=methodGetX.invoke(hct);//调用getX方法

                   returnretval;

         }

}

Eclipse小技巧:

       选择要变为方法的代码,右键——>Refactor——>ExtractMethod,然后就会生成一个方法了。

 

三、对JavaBean的复杂内省操作

        1、在IntroSpector类中有getBeanInfo(Classcls)的方法,通过此方法获取BeanInfo实例。参数是相应对象的字节码,即Class对象。

        2、BeanInfo类中有getPropertyDescriptors()的方法,可获取所有的JavaBean类中的属性信息,返回一个PropertyDescriptor[]。

        3、在通过遍历的形式,获取与想要的那个属性信息。

如:获取并调用getX方法

//第二种较复杂的获取并调用JavaBean中的getX方法

private static ObjectgetProperty2(HashCodeTest hct, String propertyName)

                   throwsIntrospectionException, IllegalAccessException,

                   InvocationTargetException{

         BeanInfobeanInfo=Introspector.getBeanInfo(hct.getClass());//创建对象关联

         PropertyDescriptor[]pds=beanInfo.getPropertyDescriptors();//获取所有的属性描述

         Objectretval=null;

                  

         //遍历

         for(PropertyDescriptor pd : pds) {

                   //如果属性跟参数的属性相等,就获取它的getX方法

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

                            MethodmethodGetX=pd.getReadMethod();//获取getX方法

                            retval=methodGetX.invoke(hct);

                            break;

                   }

         }

         returnretval;  

}

四、BeanUtils工具包

1、BeanUtils等工具包都是由阿帕奇提供的,为了便于开发。

2、BeanUtils可以将8种基本数据类型进行自动的转换,因此对于非基本数据类型,就需要注册转换器Converter,这就需要ConverUtils包。

3、好处:

       1)提供的set或get方法中,传入的是字符串,返回的还是字符串,因为在浏览器中,用户输入到文本框的都是以字符串的形式发送至服务器上的,所以操作的都是字符串。也就是说这个工具包的内部有自动将整数转换为字符串的操作。

       2)支持属性的级联操作,即支持属性链。如可以设置:人的脑袋上的眼睛的眼珠的颜色。这种级联属性的属性连如果自己用反射,那就很困难了,通过这个工具包就可以轻松调用。

4、可以和Map集合进行相互转换:可将属性信息通过键值对的形式作为Map集合存储(通过staticjava.util.Mapdescribe(java.lang.Object bean)的方法)。也可以将Map集合转换为JavaBean中的属性信息(通过staticvoid populate(java.lang.Objectbean, java.util.Map properties)的方法)。

注:要正常使用BeanUtils工具,还要将Apache公司的logging(日志)的jar包也添加进BuildPath。

示例:

package cn.itheima.demo;

 

importorg.apache.commons.beanutils.BeanUtils;

import org.apache.commons.beanutils.PropertyUtils;

 

public class IntroSpectorDemo {

         publicstatic void main(String[] args) throws Exception {

                   HashCodeTesthct=new HashCodeTest(2,3);

                   StringpropertyName="x";

                   //"x"-->"X"-->"getX"-->MethodGetX-->

                  

                   //用BeanUtils工具包的方法

                   System.out.println(BeanUtils.getProperty(hct,propertyName));//get

                   BeanUtils.setProperty(hct,propertyName, "9");//set

                  

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

                  

                   //对于JavaBean中的属性是对象的操作

                   BeanUtils.setProperty(hct,"birthday.time", "10");//set

                   System.out.println(BeanUtils.getProperty(hct,"birthday.time"));//get

         }

}

5、BeanUtils工具包中还有一个工具类PropertyUtils,用法跟BeanUtils一样。区别:

       1)BeanUtils会对JavaBean的属性的类型进行转换,如属性本身是integer,会转换为String。

       2)PropertyUtils以属性本身的类型进行操作。

如:

//用BeanUtils工具包的工具类BeanUtils方法

         BeanUtils.setProperty(hct,propertyName, "9");//set,9是String

         System.out.println(BeanUtils.getProperty(hct,propertyName));//get

         System.out.println(BeanUtils.getProperty(hct,propertyName).getClass().getName());//java.lang.String

                  

//BeanUtils工具包中的PropertyUtils的操作

         PropertyUtils.setProperty(hct,propertyName, 9);//9是Integer

         System.out.println(PropertyUtils.getProperty(hct,propertyName));

System.out.println(PropertyUtils.getProperty(hct,propertyName).getClass().getName());//java.lang.Integer

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值