黑马程序员-4-JavaBean内省操作

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

29.由内省引出JavaBean的讲解

 1.内省对应的英文单词是IntroSpector,它主要用于对JavaBean进行操作。
 2.了解JavaBean
  1)JavaBean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的
  字段,且方法名符合某种命名规则。
  2)如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象
     通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,用set()和get()
  方法来设置和获取。
  3)通过提供的set和get方法就知道属性名,一个类被当作JavaBean使用时,JavaBean的属性是根据方法名
  推断出来的,它根本看不到java类内部的成员变量。
  如果第二个字母是小写的,则把第一个字母变成小写的:
  gettime-->time
  setTime-->time
  getCPU-->CPU

  4)一个符合JavaBean特点的类可以当作普通类进行使用,但当作JavaBean用会有额外的好处。
30.对JavaBean的简单内省操作

 1.eclipse使用技巧
  1)生成get和set方法
     右键-->Source-->Generate Getters and Setters -->勾选x,y -->OK
  2)抽取方法:
  选中代码-->右键-->Refactor-->Extract Method -->输入方法名:eg:getProperty
 2.PropertyDescriptor(java.beans 包)属性描述类
  1)public class PropertyDescriptor
      extends FeatureDescriptor
     PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。
  2)构造方法摘要
  PropertyDescriptor(String propertyName, Class<?> beanClass)
          通过调用 getFoo 和 setFoo 存取方法,为符合标准 Java 约定的属性构造一个 PropertyDescriptor。
  PropertyDescriptor(String propertyName, Class<?> beanClass, String readMethodName, String writeMethodName)
          此构造方法带有一个简单属性的名称和用于读写属性的方法名称。
  PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod)
          此构造方法带有某一简单属性的名称,以及用来读取和写入属性的 Method 对象。
  3)方法摘要
   Class<?> getPropertyType()
   获得属性的 Class 对象。
  Method getReadMethod()
   获得应该用于读取属性值的方法。
  Method getWriteMethod()
   获得应该用于写入属性值的方法。
   void setReadMethod(Method readMethod)
   设置应该用于读取属性值的方法。
  void setWriteMethod(Method writeMethod)
   设置应该用于写入属性值的方法。


 3.类 FeatureDescriptor(java.beans包)
  1)public class FeatureDescriptor
        extends Object
  FeatureDescriptor 类是 PropertyDescriptor、EventSetDescriptor 和 MethodDescriptor 等的公共基类。

  它支持一些可以设置和检索任意的内省描述符的公共信息。

  此外,它还提供了一种扩展机制,从而任意属性/值对都可以与设计特性相关联。
  2)构造方法摘要
  FeatureDescriptor()
   构造一个 FeatureDescriptor。
  3)方法摘要
   String getName()
          获得此特性的编程名称。
   Object getValue(String attributeName)
          利用此特性检索指定属性。
  void setName(String name)
          设置此特性的编程名称。
   void setValue(String attributeName, Object value)
          将某一指定属性与此特性相关联。



class ReflectPoint2
{
    private int x;
    private int y;
    public int getX() {
 return x;
    }

    public void setX(int x) {
 this.x = x;
    }
    public int getY() {
 return y;
    }
    public void setY(int y) {
 this.y = y;
    }
    public ReflectPoint2(int x, int y) {
 this.x = x;
 this.y = y;
    }
}

31.对JavaBean的复杂内省操作

 1.接口 BeanInfo(java.beans 包)
  1)public interface BeanInfo希望提供有关其 bean 的显式信息的 bean 实现者可以提供某个 BeanInfo 类,
     该类实现此 BeanInfo 接口并提供有关其 bean 的方法、属性、事件等显式信息。
  请参见 SimpleBeanInfo 类,它提供了用于 BeanInfo 类的一个便捷 "noop" 基类,
  可以为那些想要返回显式信息的特定位置重写该基类。
  2)方法摘要
   MethodDescriptor[] getMethodDescriptors()
   获得 beans MethodDescriptor。
  PropertyDescriptor[] getPropertyDescriptors()
   获得 beans PropertyDescriptor。
 2.类 Introspector(java.beans)
  1)public class Introspectorextends Object
  Introspector 类为通过工具学习有关受目标 Java Bean
  支持的属性、事件和方法的知识提供了一个标准方法。

  对于这三种信息,Introspector 将分别分析 bean 的类和超类,寻找显式或隐式信息,
  使用这些信息构建一个全面描述目标 bean 的 BeanInfo 对象。
  2)方法摘要
  static BeanInfo getBeanInfo(Class<?> beanClass)
          在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。
  static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass)
          在给定的“断”点之下,在 Java Bean 上进行内省,了解其所有属性和公开的方法。
  static BeanInfo getBeanInfo(Class<?> beanClass, int flags)
          在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件,并将结果用一些控制标记表示。

/*JavaBean是一个特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法名负荷某种命名规则
 * IntroSpector-->JavaBean-->特殊的Java类
 * Age-->如果第二个字母是小的,则把第一个字母变成小的-->age 就为了好看
 *  gettime-->time
 *  setTime-->time
 *  getCPU-->CPU
 * 一个类被当作JavaBean使用时,JavaBeam的属性是根据方法名推断出来,它根本看不到java类内部的成员变量
 */
public class a29_由内省引出JavaBean的讲解 {
    public static void main(String[] args) throws Exception {

 ReflectPoint2 pt1 = new ReflectPoint2(3,5);
 String propertyName="x";
 //"x"-->"X"-->"getX"-->MethodGetX

 Object retVal = getProperty(pt1, propertyName);
 System.out.println(retVal);
 //提取方法A+S+M
 Object value=7;
 setProperty(pt1, propertyName, value);
 System.out.println(pt1.getX());
 //使用BeanUtils工具包 只能使用public类
 System.out.println(BeanUtils.getProperty(pt1, "x"));
 BeanUtils.setProperty(pt1, "x", "9");
 System.out.println(pt1.getX());
    }
  //通过内省,设置x属性的值  
    private static void setProperty(ReflectPoint2 pt1, String propertyName,
     Object value) throws Exception{
 //通过属性名,获取该对象rp下该属性x的属性描述器 
 PropertyDescriptor pd2=new PropertyDescriptor(propertyName,pt1.getClass());
 //通过属性描述器,获取该属性x的读方法,即getter方法  
 Method methodSetX= pd2.getWriteMethod();
 //利用反射调用该setter方法,设置属性x的值  
 methodSetX.invoke(pt1, value);
    }
    
  //通过内省,获取x属性的值  
    private static Object getProperty(Object pt1, String propertyName)
     throws Exception {
 PropertyDescriptor pd=new PropertyDescriptor(propertyName,pt1.getClass());
 //通过属性描述器,获取该属性x的写方法,即setter方法  
 Method methodGetX= pd.getReadMethod();
 Object retVal=methodGetX.invoke(pt1);
 return retVal;
    }
}


//通过内省,获取x属性的值  复杂操作
    private static Object getProperty(Object pt1, String propertyName)
     throws Exception {
  Object retVal=null;
  //获取该JavaBean类的beanInfo,它存储了该JavaBean的所有属性信息 
 BeanInfo beanInfo=Introspector.getBeanInfo(pt1.getClass());
 //获取该JavaBean类的所有属性描述器  
 PropertyDescriptor[] pds=  beanInfo.getPropertyDescriptors();
 for (PropertyDescriptor pd : pds) {
    if( pd.getName().equals(propertyName))//判断是否x属性的描述器   
    {
        Method methodGetX=pd.getReadMethod();
        retVal=methodGetX.invoke(pt1);
        break;
    }
 }
 return retVal;
    }
}


32.使用BeanUtils工具包操作JavaBean

 1.下载BeanUtils工具包(以jar包形式存在)
   下载commons-beanutils-current.zip-->解压-->查看API-->查看README.txt(可放在编辑器中查看)
 2.安装jar包
   工程上右键-->New-->Folder-->输入名称:lib-->将commons-beanutils.jar 拷贝到lib中
   -->在该jar包上右击-->Build Path-->Add to Build Path(此时该jar包变成了一个小奶瓶的形状)

   注意:在没有将jar包拷到工程中的lib中以前,不可以直接工程右击-->Build Path --> configure-->
   Build Path -->Add External JARS(增加外部的项)
   因为这样的话,jar包还在电脑上,而不在工程当中,此时发给别人用的时候,别人就找不到该jar包。

 3.报错:System.out.println(BeanUtils.getProperty(pt1,"x");代码报错:NoClassDefFoundError
  原因是缺少logging日志开发包。
 4.下载commos-logging-1.1-ide.zip以同样的道理,解压,拷到lib中,再增加到工程当中。

 5.java7的新特性:
  Map map = {name:"lisi",age:18};
  BeanUtils.setProperty(map,"name","zhangsan");

 6.PropertyUtils和BeanUtils的区别;
  BeanUtils接收返回的都是String类型,可自动完成属性的类型转换。
  PropertyUtils是以属性本身的类型进行操作。

public class IntrospectorTest {

	public static void main(String[] args) throws Exception{
		ReflectPoint rp=new ReflectPoint(3, 5);  
		String propertyName="x";
		
		//利用Beanutils工具包操作JavaBean类
		System.out.println(BeanUtils.getProperty(rp, propertyName));//直接获取某个对象的某个属性的值,类似例1中重构后的方法
		BeanUtils.setProperty(rp, propertyName,"9");//直接设置某个对象的某个属性的值,类似例1中重构后的方法,但注意其接收的值类型为Object,常用String类型,更符合开发实际需求
		System.out.println(rp.getX());
		System.out.println(BeanUtils.getProperty(rp, propertyName).getClass().getName());//说明该方法返回值为String类型,比例1中重构后的方法更符合开发实际需求
		
		//支持对属性链的连续调用
		BeanUtils.setProperty(rp, "birthday.time", "111");
		System.out.println(BeanUtils.getProperty(rp, "birthday.time"));
		
		//get方法返回该属性本来的类型,set方法只接受该属性本类的类型
		PropertyUtils.setProperty(rp, propertyName, 12);
		System.out.println(rp.getX());
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值