黑马程序员java学习<基础加强>—JavaBean

来源:互联网 发布:总后勤部职工数据库 编辑:程序博客网 时间:2024/06/05 18:53

一、概述:

1、IntroSpector:即内省,是对内部进行检查,了解更多的底层细节。

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

 

二、JavaBean

1、简述:

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

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

3)字段和属性:

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

而属性是具有某些功能,Bean属性,是含有get或set方法的那些属性的字段,即这个变量的get属性,set属性等。

2、作用:

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

3、命名方式:

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

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

5、JavaBean的好处:

一个符合JavaBean特点的类当做普通类一样可以使用,但是把它当做JavaBean类用肯定有好处的:

1)在JavaEE开发中,经常要使用JavaBean。很多环境就要求按JavaBean的方式进行操作,别人都这么用,那么就必须要求这么做。

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

示例:

package cn.itcast.text1;    import java.beans.BeanInfo;  import java.beans.IntrospectionException;  import java.beans.Introspector;  import java.beans.PropertyDescriptor;  import java.lang.reflect.InvocationTargetException;  import java.lang.reflect.Method;                                                                                                                                                                                                         public class IntroSpectorTest {                                                                                                       /*         public static void main(String[] args) throws Exception {               // TODO Auto-generated method stub         ReflectPoint pt1 = new ReflectPoint(3,5);         String propertyName = "x";         //"x"-->"X"-->"getX"-->MethodGetX-->         //内省的方式:         //属性描述符:PropertyDescriptor        //get属性信息         PropertyDescriptor pd =                 new PropertyDescriptor(propertyName,pt1.getClass());        Method methodGetX = pd.getReadMethod();         Object retVal = methodGetX.invoke(pt1);         System.out.println(retVal);         //set属性信息         Object value = 7;         PropertyDescriptor pd2 =                 new PropertyDescriptor(propertyName,pt1.getClass());         Method methodSetX = pd2.getWriteMethod();        methodSetX.invoke(pt1,value);                  System.out.println(pt1.getX());      }      */      //上面的get或set代码分别通过选中要重构的代码,通过右击选重构获得get和set方法:      public static void main(String[] args) throws Exception {          // TODO Auto-generated method stub          ReflectPoint pt1 = new ReflectPoint(3,5);          String propertyName = "x";          //一般方式:"x"-->"X"-->"getX"-->MethodGetX-->         //内省方式:          //通过get和set方法获取属性值          Object retVal = getProperty(pt1, propertyName);         System.out.println(retVal);                    Object value = 7;          setProperty(pt1, propertyName, value);          System.out.println(pt1.getX());      }                //设置属性值的方法             //此处的类型为Object,通用,下同      private static void setProperty(Object rf, String propertyName,              Object value) throws IntrospectionException,              IllegalAccessException, InvocationTargetException {         //创建属性描述符对象,将属性名称和加载文件等信息写入其中          PropertyDescriptor pd =                 new PropertyDescriptor(propertyName,rf.getClass());          //通过反射的方法类Method,获取属性所对应的set方法          Method methodSetX = pd.getWriteMethod();          methodSetX.invoke(rf, value);      }      //获取属性值的方法      private static Object getProperty(Object rf, String propertyName)              throws IntrospectionException, IllegalAccessException,             InvocationTargetException {          //创建属性描述符对象,获取属性所对应的名称和加载文件等信息          PropertyDescriptor pd =                  new PropertyDescriptor(propertyName,rf.getClass());          //通过反射的方法类Method,获取属性所对应的get方法          Method methodGetX = pd.getReadMethod();         Object retVal = methodGetX.invoke(rf);          return retVal;      }  }


 

三、对JavaBean的复杂内省操作:

1、在IntroSpector类中有getBeanInfo(Class cls)的方法。

2、获取Class对象的Bean信息,返回的是BeanInfo类型。

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

4、在通过遍历的形式,找出与自己想要的那个属性信息。

 

四、BeanUtils工具包:

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

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

2、好处:

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

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

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

4、示例:

1)设置和获取属性值:

import java.lang.reflect.InvocationTargetException;  import java.text.ParseException;  import java.text.SimpleDateFormat;  import java.util.Date;  import java.util.Map;  import java.util.TreeMap;     import org.apache.commons.beanutils.BeanUtils;  import org.apache.commons.beanutils.ConversionException;  import org.apache.commons.beanutils.ConvertUtils;  import org.apache.commons.beanutils.Converter;  import org.apache.commons.beanutils.PropertyUtils;  import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;  import org.junit.Test;     public class BeanUtilDemo {        /**      * BeanUtils使用      */        @Test       public void test1() throws Exception{          //创建对象,设置属性值          Person p = new Person();          BeanUtils.setProperty(p, "name", "zzz");         String name = BeanUtils.getProperty(p, "name");          System.out.println(name);      }            @Test       public void test2() throws Exception{          //创建对象,传入属性值          Person p = new Person();          String name = "wangwu";          String age = "23";          String hight = "173.5";          //设置属性值          BeanUtils.setProperty(p, "name", name);          BeanUtils.setProperty(p, "age", age);          BeanUtils.setProperty(p, "hight", hight);          //获取属性值          System.out.println(BeanUtils.getProperty(p, "name"));          System.out.println(BeanUtils.getProperty(p, "age"));          System.out.println(BeanUtils.getProperty(p, "hight"));      }  

 

2)未注册的属性值的获取和设置

//获取未注册的属性,即非八种基本数据类型的引用类型  //private Date birthday  @Test   public void test3() throws Exception{      Person p = new Person();      String name = "wangwu";      String age = "23";      String hight = "173.5";      String birthday = "1990-09-09";      ConvertUtils.register(new Converter() {          //注册器Converter接口中方法的重写          @Override          public Object convert(Class type, Object value) {             if(value == null)                  return null;              if(!(value instanceof String))                 throw new ConversionException("只支持String类型的转换");              String str = (String) value;             if(value.equals(""))                  return null;             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");              try{                  return sdf.parse(str);              }catch(ParseException e){                  throw new RuntimeException(e);//异常链不能掉,这里必须写上e              }          }},          Date.class);            //测试      BeanUtils.setProperty(p, "name", name);      BeanUtils.setProperty(p, "age", age);      BeanUtils.setProperty(p, "hight", hight);      BeanUtils.setProperty(p, "birthday", birthday);      System.out.println(BeanUtils.getProperty(p, "name"));      System.out.println(BeanUtils.getProperty(p, "age"));      System.out.println(BeanUtils.getProperty(p, "hight"));      System.out.println(BeanUtils.getProperty(p, "birthday"));   }   //使用已经写好的注册器DateLocaleConverter    @Test    public void test4() throws Exception{      Person p = new Person();      String name = "wangwu";      String age = "23";      String hight = "173.5";      String birthday = "1990-09-09";      //将日期注册到BeanUtils上     ConvertUtils.register(new DateLocaleConverter(), Date.class);//提供的注册器不健壮,因为传入空字符串,就会报错                                                                  //所以,当没有提供注册器或需要加强注册器的时候,可以自己写      //测试      BeanUtils.setProperty(p, "name", name);      BeanUtils.setProperty(p, "age", age);      BeanUtils.setProperty(p, "hight", hight);      BeanUtils.setProperty(p, "birthday", birthday);      System.out.println(BeanUtils.getProperty(p, "name"));      System.out.println(BeanUtils.getProperty(p, "age"));      System.out.println(BeanUtils.getProperty(p, "hight"));      System.out.println(BeanUtils.getProperty(p, "birthday"));      Date date = p.getBirthday();      System.out.println(date.toLocaleString());  }  



3)Map集合在BeanUtils中的应用:

//Map集合在BeanUtils中的应用  @Test  public void test5() throws Exception {      /*      * JDK 7.0新特性:       * Map map = {"name" : "zs", "age" : 22, "hight" : 176.5};     */      //将数据存入集合      Map map = new TreeMap();      map.put("name", "zhangsan");      map.put("age", "20");      map.put("hight", "172.5");      map.put("birthday", "1999-10-02");            //注册器      ConvertUtils.register(new DateLocaleConverter(), Date.class);      //获取属性      Person p = new Person();      BeanUtils.populate(p, map);             System.out.println(BeanUtils.getProperty(p, "name"));      System.out.println(BeanUtils.getProperty(p, "age"));      System.out.println(BeanUtils.getProperty(p, "hight"));      System.out.println(BeanUtils.getProperty(p, "birthday"));        }  //属性链  @Test  public void test6() throws Exception {      Person p = new Person();      BeanUtils.setProperty(p, "birthday.time", "111212");      System.out.println(BeanUtils.getProperty(p, "birthday.time"));  }  


 

5、补充:

1)BeanUtils是以字符串的形式进行操作的

2)PropertyUtils是以传入值本身的类型进行操作的。

//PropertyUtils可直接解析为指定类型,而BeanUtils只能指定字符串的类型      @Test      public void test7() throws Exception {          Person p = new Person();          System.out.println("-----BeanUtiles-------");          BeanUtils.setProperty(p, "age", "22");//字符串形式          System.out.println(BeanUtils.getProperty(p, "age"));          System.out.println(BeanUtils.getProperty(p, "age").getClass().getName());                    System.out.println("-----PropertyUtiles-------");          PropertyUtils.setProperty(p, "age", 22);//Integer形式          System.out.println(PropertyUtils.getProperty(p, "age"));          System.out.println(PropertyUtils.getProperty(p, "age").getClass().getName());      }  


 

原创粉丝点击