`
Ivan0513
  • 浏览: 211749 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

(1)反射getter And setter

阅读更多

近来封装了很多发射的小方法,使用过程中,发觉发射的好处是:当很多类有共性时,使用发射,可以达到只做一次,到处使用的效果。就像Hibernate一样,save(obj),我并不需要知道obj到底是哪个类,Hibernate自动会正确的把记录保存到数据库!

 

备注:

我使用反射封装一些小方法,是为了对大部分有共性的方法通用,所以要求,

a.类的属性必须有getXXX与setXXX方法;

b.getXXX,setXXX,XXX必须与类的字段名一致,而首字母大写;

c.getXXX是无参的,setXXX参数只能有1个,而且类型必须与属性一致(除了基础数据类型,他们可以自动打包)

d.最好有一个无参构造函数

 

我将有关反射的方法都放入了BeanReflectUtil,作为工具类使用。

 

准备一个简单的类(我的小方法也就只能对简单的类其作用)

public class Person {

	private String name;
	private int age;
	private Date birthday;
	
	public Person() {
	}
	
	public Person(String name, int age, Date birthday) {
		super();
		this.name = name;
		this.age = age;
		this.birthday = birthday;
	}

	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;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}

 

 

1.封装getter

/***
* 组装类中某个属性的get方法名称
* StringUtil.upperFirst(String str)是自己封装的,将首字母变大小的小方法;
* @param c
* @param filedName
* @return
* @throws SecurityException
* @throws NoSuchMethodException
*/
public static Method assembleGetMethod(Class<?> c, String filedName)  throws SecurityException, NoSuchMethodException {
    String methodName = "get" + StringUtil.upperFirst(filedName);
    Class<?>[] nullClasses = null;
    return c.getDeclaredMethod(methodName, nullClasses);
}

 调用方法实例:

Method m = BeanReflectUtil.assembleGetMethod(Person.class, "name");
m.invoke(new Person("jack"), null);

 为了进一步——偷懒,将封装一个小方法:

public static Object invokeGetMethod(Class<?> c, String filedName, Object obj) 
  throws SecurityException, NoSuchMethodException, IllegalArgumentException, 
  IllegalAccessException, InvocationTargetException {
  Method method = assembleGetMethod(c, filedName);
  Object[] nullObjects = null;
  return method.invoke(obj, nullObjects);
 }

 那么,我们使用某个属性的getter方法时,只需要

BeanReflectUtil.invokeGetMethod(Person.class, "name", new Person("jack"));

 就可以了。

 

 2.封装setter方法

与getter方法不一样的地方是:getXXX()是无参的,

所以,封装的时候,需要告诉他参数的类型;调用的时候,要给一个参数!

/***
 * 组装类中某个属性的set方法名称
 * @param c 要封装哪个类
 * @param filed 封装哪个属性
 * @return
 * @throws SecurityException
 * @throws NoSuchMethodException
 */
public static Method assembleSetMethod(Class<?> c, Field field) 
 throws SecurityException, NoSuchMethodException {
 String methodName = "set" + StringUtil.upperFirst(field.getName());
 Class<?>[] parameterClasses = new Class[]{field.getType()}; //告诉Java该set方法的参数类型
 return c.getDeclaredMethod(methodName, parameterClasses);
}

 调用:

Method setMethod = BeanReflectUtil.assembleSetMethod(Person.class, Person.class.getDeclaredField("name"));
Person p = new Person();
setMethod.invoke(p, "jack");
System.out.println(p.getName());

 想进一步偷懒,可以

/**
 * 封装Set方法,并立刻调用
 * @param c 为哪个类封装Set方法
 * @param fieldName 属性名称
 * @param obj 为哪个对象赋值
 * @param fieldValue 赋的值
 */
public static void invokeSetMethod(Class<?> c, String fieldName, Object obj, Object fieldValue) 
	throws SecurityException, NoSuchFieldException, 
		NoSuchMethodException, IllegalArgumentException, 
		IllegalAccessException, InvocationTargetException {
	Field f = c.getDeclaredField(fieldName);
	Method setMethod = assembleSetMethod(c, f);
	setMethod.invoke(obj, fieldValue);
}

 

调用方法:

invokeSetMethod(Person.class, "name", p, "Mike");
System.out.println(p.getName());

 

但,实际使用中,应该不会用到,

我的想象场景是:有一堆Map<Person p, String name>

我获得set方法后,会为很多Map中的Person的name属性赋上Map中的name值,

所以,不会组装好set后就马上调用,这样效率也太低了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics