?Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
在学设计模式的时候,我们看到过一句话:“反射反射,程序员的快乐”,当时对这句话没有很深刻的认识,到学习了struts、spring等之后,感觉到反射真是很强大的存在。
我们今天介绍如何通过Java的反射,获取对象的信息。需求是这样的:有一个实体,实体里面有多个属性,通过这个实体中有值的属性做检索条件,就是如果某一个属性有值,那么这个属性就是一个检索条件,如果某一个属性没有值,那么这个属性就不作为检索条件。这样一个方法比较通过,而且在很大的程度上提高了代码的复用型,那么我们如果通过一个实体拿到其所有的属性呢?答案是——反射!
? public List queryByEntity(Object model,String cont) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
? ? ? Map map=new HashMap();?
? Field[] field = model.getClass().getDeclaredFields();? ? ? ? //获取实体类的所有属性,返回Field数组
? ? ? ? for(int j=0 ; j? ? ? ? ? ? ? ? String name = field[j].getName();? ? //获取属性的名字?
? ? ? ? ? ? ? ? System.out.println("属性名:"+name);? ?
? ? ? ? ? ? ? ? String anotherName=name;
? ? ? ? ? ? ? ? name = name.substring(0,1).toUpperCase()+name.substring(1); //将属性的首字符大写,方便构造get,set方法
? ? ? ? ? ? ? ? String type = field[j].getGenericType().toString();? ? //获取属性的类型
? ? ? ? ? ? ? ? if(type.equals("class java.lang.String")){? //如果type是类类型,则前面包含"class ",后面跟类名
? ? ? ? ? ? ? ? ? ? Method m = model.getClass().getMethod("get"+name);
? ? ? ? ? ? ? ? ? ? String value = (String) m.invoke(model);? ? //调用getter方法获取属性值
? ? ? ? ? ? ? ? ? ? if(value != null){
? ? ? ? ? ? ? ? ? ? ?//把属性名和值放入map中;
? ? ? ? ? ? ? ? ? ? map.put(anotherName, value);
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if(type.equals("class java.lang.Integer")){? ?
? ? ? ? ? ? ? ? ? ? Method m = model.getClass().getMethod("get"+name);
? ? ? ? ? ? ? ? ? ? Integer value = (Integer) m.invoke(model);
? ? ? ? ? ? ? ? ? ? if(value != null){
? ? ? ? ? ? ? ? ? ? ?//把属性名和值放入map中;
? ? ? ? ? ? ? ? ? ? map.put(anotherName, value);
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if(type.equals("class java.lang.Short")){? ?
? ? ? ? ? ? ? ? ? ? Method m = model.getClass().getMethod("get"+name);
? ? ? ? ? ? ? ? ? ? Short value = (Short) m.invoke(model);
? ? ? ? ? ? ? ? ? ? if(value != null){
? ? ? ? ? ? ? ? ? ? ?//把属性名和值放入map中;
? ? ? ? ? ? ? ? ? ? map.put(anotherName, value);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }? ? ?
? ? ? ? ? ? ? ? if(type.equals("class java.lang.Double")){? ?
? ? ? ? ? ? ? ? ? ? Method m = model.getClass().getMethod("get"+name);
? ? ? ? ? ? ? ? ? ? Double value = (Double) m.invoke(model);
? ? ? ? ? ? ? ? ? ? if(value != null){? ?
? ? ? ? ? ? ? ? ? ? ?//把属性名和值放入map中;
? ? ? ? ? ? ? ? ? ? map.put(anotherName, value);
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(type.equals("class java.lang.Boolean")){
? ? ? ? ? ? ? ? ? ? Method m = model.getClass().getMethod("get"+name);?
? ? ? ? ? ? ? ? ? ? Boolean value = (Boolean) m.invoke(model);
? ? ? ? ? ? ? ? ? ? if(value != null){? ? ?
? ? ? ? ? ? ? ? ? ? ?//把属性名和值放入map中;
? ? ? ? ? ? ? ? ? ? map.put(anotherName, value);
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if(type.equals("class java.util.Date")){
? ? ? ? ? ? ? ? ? ? Method m = model.getClass().getMethod("get"+name);? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? Date value = (Date) m.invoke(model);
? ? ? ? ? ? ? ? ? ? if(value != null){
? ? ? ? ? ? ? ? ? ? ?//把属性名和值放入map中;
? ? ? ? ? ? ? ? ? ? map.put(anotherName, value);
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }? ? ? ? ? ? ?
? ? ? ? ? ? }
}
通过这些代码,我们已经能获取到该实体中,所有不为null的属性,并且将之存在了map中。获取到这些之后,我们就可以很方便的做检索。
总结:
Java的反射不仅仅体现在这一点上,java的反射还在很多地方发挥着及其重要的作用,因为反射,我们可以提高系统的灵活性。如struts中,请求的派发控制。当请求来到时,struts通过查询配置文件,找到该请求对应的action,然后通过反射实例化action,并调用响应method。如果不适用反射,那么就只能写死到代码里了。