Java反射之对JavaBean的内省操作

上一篇我们说了Java反射之数组的反射应用
这篇我们来模拟实现那些javabean的框架(BeanUtils)的基本操作。

[一] 什么是JavaBean

JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,通过set和get方法获取。
一般我们根据这种方法命名规则,通过反射获得某个或者设置某个属性的时候,假如这个属性名为”x",那么,就会处理以下几步:
1、将x变为大写X,判断x后是否还有字母,有则首字母大写
2、在x前加get

[二] 对JavaBean的复杂内省操作

这是一种比较笨重的方式:
Bean类:

package club.leyvan.muzile;

public class Bean {
	private int x = 10;
	private int y = 20;
	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 static void main(String[] args) throws Exception {
		Bean bean = new Bean();
		System.out.println(getProperty(bean, "x"));
		setProperty(bean, "y", 8);
		System.out.println(getProperty(bean,"y"));
	}
	
	/**
	 * 根据属性名获得属性方法
	 * @param obj
	 * @param propertyName
	 * @return
	 * @throws Exception
	 */
	public static Object getProperty(Object obj,String propertyName) throws Exception{
		Object retVal = null;
		//通过内省获得描述对象
		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
		//通过描述对象获得该类的所有属性描述
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		//迭代所有属性,获得与规则相同的方法。
		for(PropertyDescriptor pd : pds){
			//如果该属性的名称与方法形参一致
			if(pd.getName().equals(propertyName)){
				//则调用该属性的get方法
				Method method = pd.getReadMethod();
				//get方法都是无参数的
				retVal = method.invoke(obj);
			}
		}
		
		return retVal;
	}
	
	/**
	 * 根据属性名设置属性的方法
	 * @param obj
	 * @param propertyName
	 * @param value
	 * @throws Exception
	 */
	public static void setProperty(Object  obj,String propertyName,Object value) throws Exception{
		//通过内省获得描述对象
				BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
				//通过描述对象获得该类的所有属性描述
				PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
				//迭代所有属性,获得与规则相同的方法。
				for(PropertyDescriptor pd : pds){
					//如果该属性的名称与方法形参一致
					if(pd.getName().equals(propertyName)){
						//则调用该属性的set方法
						Method method = pd.getWriteMethod();
						//set方法传入参数
						method.invoke(obj,value);
					}
				}
	}

结果:

10
8

将原本等于20的y改为了8

[三] 对JavaBean的简单内省操作

上面是一种笨拙的方式,有更为简单的方法:

	public static void main(String[] args) throws Exception {
		Bean bean = new Bean();
		System.out.println(getProperty(bean, "x"));
		setProperty(bean, "y", 39);
		System.out.println(getProperty(bean,"y"));
	}
	
	public static Object getProperty(Object obj,String propertyName) throws Exception{
		Object retVal = null;
		//直接获得属性描述对象
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
		//根据属性,获得get方法
		Method method = pd.getReadMethod();
		//调用方法
		retVal = method.invoke(obj);
		return retVal;
	}
	
	public static void setProperty(Object  obj,String propertyName,Object value) throws Exception{
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
		Method method = pd.getWriteMethod();
		method.invoke(obj, value);
	}

结果:

10
39

本期Java反射就介绍到这,谢谢大家!

posted @ 2020-03-11 13:01  阿尔伯特-李古拉-逸凡  阅读(181)  评论(0编辑  收藏  举报