Java高新技术之JavaBean(内省 IntroSpector)


一、Javabean

1.JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,大家觉得这些方法的名称叫什么好呢?JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你把它存到哪个变量上,用管吗?如果方法名为getId,中文意思即为获取id,至于你从哪个变量上取,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。

  • setId()的属性名---->id
  • isLast()的属性名---->last
  • setCPU的属性名是什么?---->CPU
  • getUPS的属性名是什么?---->UPS
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
2.一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean!好处如下:
  • 在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地!
  • JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,怎么做,有一定难度吧?用内省这套api操作JavaBean比用普通类的方式更方便。
二、PropertyDescriptor  BeanInfo BeanUtils PropertyUtils操作javabean  见代码所示:
import java.util.Date;

public class Person
{
	  private String name;
	  private int age;
	  private Date birthday=new Date();//这里要创建对象!
	
    public Date getBirthday()
	{
		return birthday;
	}
	public void setBirthday(Date birthday)
	{
		this.birthday = birthday;
	}
	public Person(String name, int age)
	{
		super();
		this.name = name;
		this.age = age;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public int getAge()
	{
		return age;
	}
	public void setAge(int age)
	{
		this.age = age;
	}
	
	@Override
	public String toString()
	{
		return this.name+" "+this.age+" "+this.birthday;
	}
  
  
}
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;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

public class IntrospectorTest
{

	/**
	 * 各种类操作javabean
	 */
	public static void main(String[] args)throws Exception
	{
		Person p=new Person("张三",23);
		String propertyName="name";
		//1.以下使用PropertyDescriptor操作javabean
		getProperty(p, propertyName);
		
		Object val="张凯";
		setProperty(p, propertyName, val);
		
		//2.以下使用BeanInfo操作javabean
		getPropertyByBeanInfo(p, propertyName);
		
		//3.以下使用BeanUtils操作javabean。
		BeanUtils.setProperty(p, propertyName,"李四" );
		//这是属性链,birthday是Date类型的,Date中有setTime(long time)方法
		BeanUtils.setProperty(p, "birthday.time","11111");
		System.out.println(BeanUtils.getProperty(p, "birthday.time"));
		//BeanUtils操作中参数是String类型的 返回结果也是String类型
		System.out.println(BeanUtils.getProperty(p, "birthday.time").getClass().getName());
		
		//4.PropertyUtils操作javabean
		PropertyUtils.setProperty(p, "name", "lily");
		PropertyUtils.setProperty(p, "age", 30);//传入是是int
		System.out.println(PropertyUtils.getProperty(p, "age").getClass().getName());//返回是Integer
		PropertyUtils.setProperty(p, "birthday.time", 10000);
		System.out.println(p);
		

	}
	public static void getPropertyByBeanInfo(Person p, String propertyName)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException
	{
		BeanInfo beanInfo=Introspector.getBeanInfo(p.getClass());
		PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
		//遍历数组找到指定属性
		for(PropertyDescriptor pd:pds)
		{
			if(pd.getName().equals(propertyName))
			{
			  System.out.println(pd.getReadMethod().invoke(p));
				break;
			}
		}
	}
    //设置属性方法
	public static void setProperty(Person p, String propertyName, Object val)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException
	{
		PropertyDescriptor pd1=new PropertyDescriptor(propertyName,p.getClass());
		Method methodSet=pd1.getWriteMethod();
		methodSet.invoke(p, val);//调用set方法把name值设置为“张凯”
		System.out.println(p);
	}
	
	//得到属性方法
	private static void getProperty(Person p, String propertyName)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException
	{   
		//获取javaBean的属性描述
		PropertyDescriptor pd=new PropertyDescriptor(propertyName,p.getClass());
		//得到方法
		Method methodGet=pd.getReadMethod();
		System.out.println(methodGet.invoke(p));//调用方法
	}

}

三、其他
用struts的迭代标签不能迭代出枚举元素的属性,而用jstl的迭代标签则可以。采用BeanUtils去获取带有抽象方法的枚举类的成员对象的属性时,会出现错误,要自己用内省加暴力反射方式才可以获取。主要原因是枚举类的抽象子类不是public类型的。
public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*System.out.println(
		PropertyUtils.getProperty(Sex.NONE, "title"));*/
	
		Object bean = Sex.NONE;
		BeanInfo beanInfo = null;
		try {
			beanInfo = Introspector.getBeanInfo(bean.getClass());
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	
		PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
		for(PropertyDescriptor property:properties)
		{
			if(property.getName().equals("title"))
			{
				Method method = property.getReadMethod();
				method.setAccessible(true);
				Object retVal;
				try {
					retVal = method.invoke(bean, null);
    				System.out.println(retVal);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}		
	}




你可能感兴趣的:(java,Date,exception,String,properties,object)