62.黑马程序员-内省

来源:互联网 发布:js click target 编辑:程序博客网 时间:2024/04/30 10:04

------- android培训、java培训、期待与您交流! ----------

  • 什么是内省?
    • JDK给JavaBean提供的API称为内省。
    • 内省(IntroSpector)是Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。
  • 怎么使用内省?
    • Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),
    • 这些 API 存放于包 java.beans 中,
      • 一般的做法是通过类 Introspector 的 getBeanInfo方法 来获取某个对象的 BeanInfo 信息,
      • 然后通过 BeanInfo 来获取属性的描述器(PropertyDescriptor),
      • 通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,
      • 然后我们就可以通过反射机制来调用这些方法。
  • 什么是JavaBean?
    •  一个JavaBean类可以不当JavaBean用,而当成普通类用。
    • JavaBean实际就是一种规范,当一个类满足这个规范,这个类就能被其它特定的类调用。
    • 一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
    • 去掉set前缀,然后取剩余部分,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
      • 下面就用前面的讲解的反射方式来设置或读取JavaBean的属性:
      •         import java.beans.BeanInfo;
      •         import java.beans.IntrospectionException;
      •         import java.beans.Introspector;
      •         import java.beans.PropertyDescriptor;
      •     除了反射用到的类需要引入外,内省需要引入的类如上所示,它们都属于java.beans包中的类,自己写程序的时候也不能忘了引入相应的包或者类。下面代码片断是一个设置某个JavaBean类某个属性的关键代码:
      • private static void setObjectProperty(ReflectPoint pt1, int value,String propName) throws IntrospectionException, IllegalAccessException, InvocationTargetException {            /*BeanInfo bean = Introspector.getBeanInfo(ReflectPoint.class);            PropertyDescriptor [] properties = bean.getPropertyDescriptors();            for(PropertyDescriptor property: properties)            {                if(property.getName().equals(propName))                {                    Method mSetX = property.getWriteMethod();                    mSetX.invoke(pt1, value);                    break;                }            }*/            PropertyDescriptor property = new PropertyDescriptor("x",ReflectPoint.class);            Method mSetX = property.getWriteMethod();            mSetX.invoke(pt1, value);        }
  • JavaBean有什么好处?
    • JavaEE开发中,很多环境要求使用JavaBean方式进行操作。
    • 两个模块传递多个信息,需要把这些信息封装成一个JavaBean中,称为值对象(传递值的对象,简写为VO)。
    • 我们又通常把javabean的实例对象称之为值对象(Value Object),因为这些bean中通常只有一些信息字段和存储方法,没有功能性方法。
  • 总结:
    • 代码中注释的语句代表一种方式,最后的三行代表另外一种设置相应类相应属性的方式。
    • 从简洁上来说,第二种方式显然更优雅。第一种方式中首先是获得相应javaBean的类信息bean,用的BeanInfo这个类来描述的。然后就能够通过getPropertyDescriptors方法获取属性描述数组对象。最后从数组中取去一个个的属性对象进行操作——获取相应的读写方法,然后调用相应的读写方法。这些是通过反射机制做到的。由于这种方式比较麻烦,如果只调用其中一种方法,就要遍历一次属性描述数组,所以就产生了第二种方式,直接通过传入属性名称,相应的javaBean类型参数,构造出一个需要的PropertyDescriptor对象,然后再进行调用。
    • 理解了相应的原理,那些现成的工具用起来就会更舒服,如Beanutils与PropertyUtils工具。这两个工具设置属性的时候一个主要区别是PropertyUtils.getPropety方法获得的属性值的类型为该属性本来的类型,而BeanUtils.getProperty则是将该属性的值转换成字符串后才返回。
  • 另:beanutils工具包
    • 使用beanutils工具包操作JavaBean(需导入beanutils工具包和logging日志包):
    • BeanUtils.getProperty(pt1,"x");
    • BeanUtils.setProperty(pt1,"x","9");
    • get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。
    • /*
    • Java7新特性:
    • Map map = {name:"xxx",age:18};
    • BeanUtils.setProerty(map,"name","lhm");
    • */
    • PropertyUtils.getProperty(pt1,"x");
    • PropertyUtils.setProperty(pt1,"x",9);
    • get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。


 

原创粉丝点击