Java内省机制的学习心得

内省机制(内省机制的学习需要先了解JavaBean规范)

通过内省类(Introspector)可以生成对应字节码对象的BeanInfo类(包含了三大成员 -----> 事件、方法、属性)。一般对BeanInfo类中的属性(Property)进行操作。

 

BeanInfo类中的属性(Property)是通过符合javabean规范的get/set方法推导出来的。(只要方法名的前缀是get或set,后面的字符串首字母小写后就是一个属性的名字)

 

规范的get方法-读方法:public修饰,无参数,有返回,get开头.

规范的set方法-写方法:public修饰,有参数,无返回,set开头.

 

注意:

  1. 只要是标准的get/set方法,就存在属性。(不一定是成员变量)
  2. Javabean规范中,返回值是boolean的,读方法不是get开头,是is开头

最后附赠一个内省机制操作Bean属性的工具类和测试代码

(验证测试代码时:需要lombok的jar包;或者按照JavaBean规范重写测试代码中的Person类)

package cn.web03;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @name:        MyBeanUtils
 * @Description: JavaBean属性操作工具类
 * @Author:	 leaf
 * @CreateDate:  2019年12月5日
 * @Version: 	 V1.0
 */
public class MyBeanUtils {
	
	private static final MyBeanUtils myBeanUtils=new MyBeanUtils();
	private MyBeanUtils() {}
	public static MyBeanUtils getInstance() {
		return myBeanUtils;
	}
	
	/**
	* @Name:        setPropertyValue
	* @Description:	根据指定的bean实例对象,给指定属性名称的属性设置对应属性值
	* @Author:      leaf
	* @Version:     1.0
	* @CreateDate:	2019年12月5日
	* @Parameters:	String propertyName 	属性名称
	* @Parameters:	Object propertyValue 	属性值
	* @Parameters:	Object bean             bean实例对象
	* @Return:      void
	 */
	public void setPropertyValue(String propertyName,Object propertyValue,Object bean) {
		try {
			PropertyDescriptor pd = new PropertyDescriptor(propertyName,bean.getClass());
			if(!pd.getPropertyType().equals(propertyValue.getClass())){
				throw new Exception("属性类型不匹配!该属性的类型是"+pd.getPropertyType()+",你输入的类型是"+propertyValue.getClass());
			}
			Method m = pd.getWriteMethod();
			if(m!=null) {
				m.invoke(bean, propertyValue);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	* @Name:        getPropertyValue
	* @Description:	根据指定的bean对象的属性名称,获取属性值
	* @Author:      leaf
	* @Version: 	V1.0
	* @CreateDate:  2019年12月5日
	* @Parameters: 	propertyName 属性名称
	* @Parameters: 	bean bean实例对象
	* @Return:      Object 返回getter方法的返回值,即属性值
	*/
	public Object getPropertyValue(String propertyName,Object bean) {
		Object propertyValue = null;
		try {
			PropertyDescriptor pd = new PropertyDescriptor(propertyName,bean.getClass());
			Method m = pd.getReadMethod();
			if(m!=null) {
				propertyValue = m.invoke(bean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return propertyValue;
	}
	
	/**
	* @Name:        bean2Map
	* @Description:	把bean的实例对象转换成Map
	* @Author:      leaf
	* @Version:     1.0
	* @CreateDate:	2019年12月6日
	* @Parameters:	Object bean    bean实例对象
	* @Return:     Map<String,Object>
	 */
	public Map<String,Object> bean2Map(Object bean){
		Map<String,Object> map = new HashMap<>();
		try {
			BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
			PropertyDescriptor[] pds = bi.getPropertyDescriptors();
			for (PropertyDescriptor pd : pds) {
				String key = pd.getName();
				Method m = pd.getReadMethod();
				if(m!=null) {
					Object obj = m.invoke(bean);
					map.put(key, obj);
				}
			} 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	* @Name:        map2Bean
	* @Description:	把Map中的数据传给Bean实例对象
	* @Author:      leaf
	* @Version:     1.0
	* @CreateDate: 2019年12月5日
	* @Parameters:  Map<String,Object> map	存储数据的map集合
	* @Parameters:  Object bean             Bean的实例对象
	* @Return:      void
	 */
	public void map2Bean(Map<String,Object> map,Object bean) {
		try {
			BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
			PropertyDescriptor[] pds = bi.getPropertyDescriptors();
			for (PropertyDescriptor pd : pds) {
				String key = pd.getName();
				Method m = pd.getWriteMethod();
				if(m!=null && map.containsKey(key)) {
					m.invoke(bean, map.get(key));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}


//测试代码
package cn.web03;

import java.util.Map;
import java.util.Set;

import org.junit.Test;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/**
 * @name:        TestMyBeanUtils
 * @Description: 测试MyBeanUtils类的测试类
 * @Author:      leaf
 * @CreateDate:  2019年12月6日
 * @Version: 	 V1.0
 */
public class TestMyBeanUtils {
	@Getter             //成员变量的getter方法
	@Setter             //成员变量的setter方法
	@NoArgsConstructor  //无参构造器
	@AllArgsConstructor //全参构造器
	@ToString           //toString
	@EqualsAndHashCode  //equals和hashCode
	private class Person{
		private String name;
		private Integer age;
	}
	Person p = new Person("黄华",18);
	
	private MyBeanUtils utils = MyBeanUtils.getInstance();
	
	/**
	* @Name:        testSetPropertyValue
	* @Description:	测试setPropertyValue方法。根据指定的bean实例对象,给指定属性名称的属性设置对应属性值
	* @Author:      leaf
	* @Version:     1.0
	* @CreateDate:  2019年12月6日
	* @Parameters:  null
	* @Return:      void
	 */
	@Test
	public void testSetPropertyValue(){
		utils.setPropertyValue("name", "黄辉", p);
		utils.setPropertyValue("age", 20, p);
		System.out.println(p);
		System.out.println("-------------------------");
	}
	
	/**
	* @Name:        testGetPropertyValue
	* @Description: 测试getPropertyValue方法。根据指定的bean对象的属性名称,获取属性值
	* @Author:      leaf
	* @Version:     1.0
	* @CreateDate:  2019年12月6日
	* @Parameters:  null
	* @Return:      void
	 */
	@Test
	public void testGetPropertyValue() {
		Object name = utils.getPropertyValue("name", p);
		Object age = utils.getPropertyValue("age", p);
		System.out.println(name+","+age);
		System.out.println("-------------------------");
	}
	
	/**
	* @Name:        testBean2Map
	* @Description: 测试map2Bean方法和bean2Map方法。把bean的实例对象转换成Map,把Map中的数据传给Bean实例对象
	* @Author:      leaf
	* @Version:     1.0
	* @CreateDate:  2019年12月6日
	* @Parameters:  null
	* @Return:      void
	 */
	@Test
	public void testBean2Map() throws Exception {
		Map<String,Object> map = utils.bean2Map(p);
		Set<String> set = map.keySet();
		for (String str : set) {
			System.out.println(str+":"+map.get(str));
		}
		
		System.out.println("-------------------------");
		
		map.put("name", "黄迪");
		map.put("age", 28);
		
		utils.map2Bean(map, p);
		System.out.println(p);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值